building flexible and reusable class hierarchy - c#

Let's review some entities:
Company;
Collaborator;
Chief;
Subordinate workers.
There are some rules:
Collaborator could be one of these: Sales, Manager,
Employee;
Sales and Manager could have subordinate workers (of any type decribed in the 1st rule);
Sales, Manager, Employee could have chief;
Each role has its own Salary
calculation method.
So the target is to create flexible & reusable class hierarchy.
First thing that confuses me is "can have" phrase. Should it be implemented as a composition? If it is said "can have as many" should it be a composition with list of objects?
Should I create abstract class Collaborator and then inherit from it 3 other types or there is more smart way?
What is the best way to tie all the entities together and have good reusable assembly?

"Can have" and the fact that its followed by "workers", tells me this is a "has a" relationship (composition) with a 0 to many relationship (so a list as you mention that could be empty)
An abstract class Collaborator seems reasonable.

Can have is represented in UML as (0..*) which means either 0 or more, yes composition with a list of objects would be good, use collections not an array.
Collaborator is an Abstract class since there will be no instances of Collaborator itself. Inheriting the 3 types of Collaborator is the best way I guess.
I have to add that, if you only have one company in your project, you need to implement the Singleton design pattern.
About the Salary use virtual method and override it.
I hope this is not your homework ;)

I find the question poorly formulated, the design can change severly by just adding small extra information.
Based on what you wrote, I might consider creating the following classes ('-' means extends):
Company
AbstractCollaborator (Chief member, CalculateSalary() { return base + AdditionalSalary() }, abstract AdditionalSalary())
- Chief
- AbstractLeader ( List subordinates )
-- Sales
-- Manager
- Employee
Chief would have no chief set for itself. I would try to prevent using virtual functions, and try using abstract functions instead.
Another option would be to simply using one class. It's all nice and well that only Sales or Manager can have subordinates, but in a real world situation it might be necessary for anyone to have subordinates. The function of any type of employee could simply be specified by a enum value instead.
It all depends greatly at where you are going with this ...

I guess the answer to this question is subjective and would change depending on your needs but this is how I would implement it:
public class Company {
public List<Collaborator> Collaborators { get; set; }
}
public abstract class Collaborator {
public Collaborator(Company company) {
company.Collaborators.Add(this);
}
public virtual Decimal Salary(object value);
public Company Company { get; set; }
}
public class Sales : Collaborator {
public override Decimal Salary(object value) {}
public List<Collaborator> Subordinates { get; set; }
public Collaborator Chief { get; set }
}
public class Manager : Collaborator {
public override Decimal Salary(object value) {}
public List<Collaborator> Subordinates { get; set; }
public Collaborator Chief { get; set }
}
public class Employee : Collaborator {
public override Decimal Salary(object value) {}
public Collaborator Chief { get; set }
}
This code has not been tested.

Related

What is the difference between Abstraction and Inheritance?

I could not find this question anywhere. Based upon my understanding, Inheritance should/might be the subset of Abstraction.
First of you should be aware, that here is always some leeway in interpreting such terms and concepts. Below is my take on it.
Abstraction is the concept while inheritance is a technical realization.
Abstraction in general refers to the leaving out of (unnecessary) details. The opposite direction is concretization. Generalization is also often used in this context and basically means the same as abstraction.
In the context of computer science this can be used to describe several ideas:
One is the modelling of domain concepts. As in the class Car is an abstraction of real world automobiles. It uses an engine and four wheels to transport 1-5 people. Obviously this is nowhere near the informational density to describe a real car, but it may very well be all that is needed for the context of this application.
An other is to use it to describe the conceptual relation between multiple domain entities: A Car is a Motorvehicle. A Bus is also a Motorvehicle. Both are used to transport people. The Motorvehicle is the abstraction of both Car and Bus. It describes the idea of transporting people, while leaving out the detail of how many.
A third is the difference between an interface and an implementation. The interface abstracts the implementation by hiding the implementation details and only representing the surface area with which one may interact.
Inheritance is one method of realizing abstractions in code. It describes the process of taking a base class (this is the more general or abstract thing), inheriting all of its features/properties/behavior/meaning and adding some more details (or overriding some of the existing) to create the derived class (this is the more concrete thing).
First, When you mark a class as abstract you cannot create an instance. Abstract classes are used to be inherited only.
But when you inherited from a non abstract class you can create instance from both of derived and base classes. So you can say abstract classes are used to generate new types, to be inherited not to create instance !
This is also somehow related polymorphism.
For example you have a base Employee class like below:
public class Employee
{
public string Name { get; set; }
public double Salary { get; set; }
public void IncreaseSalary(double rate)
{
this.Salary += (this.Salary * rate / 100);
}
}
Now when we create SalesRepresentative class like below we should inherit it from Employee because SalesRepresentative is an Employee.
public class SalesRepresentative : Employee
{
public double AnnualSalesAmount { get; set; }
}
Now SalesRepresentative object has IncreaseSalary method because it is inherited from Employee. But in generally Sales Representatives' and Employee's Salaries are increased by different ways for example according to their AnnualSalesAmount.
In this case you should be able to change method code of IncreaseSalary from SalesRepresentative but you can't. Actually now you are across with Polymorphism
Now Let's come to abstraction. If you want to change the default code of IncreaseSalary from inherited class there are 2 choices. First marking the method as Virtual. And the second one is marking it as abstract.
The difference is If you mark it as virtual. You don't have to implement it in SalesRepresentative but If you mark it as abstract you have to implement it and you should forget an abstract member can only be in abstract classes. Examine the example below:
public abstract class Employee
{
public string Name { get; set; }
public double Salary { get; set; }
public abstract void IncreaseSalary(double rate);
}
public class SalesRepresentative : Employee
{
public double AnnualSalesAmount { get; set; }
public override void IncreaseSalary(double rate)
{
if (this.AnnualSalesAmount > 100000)
{
this.Salary += (this.Salary * (rate + 5) / 100);
}
else
{
this.Salary += (this.Salary * rate / 100);
}
}
}

Can i use the same properties for different classes?

I'm supposed to find the classes and their responsibilities from the problem statement.
The bank offers the following type of accounts to its customers: savings account, checking account, and money market account. customers are allowed to withdraw (decrease) and deposit (increase) money into those accounts.
my question is:
Can I create 3 different classes that use the same 2 properties (increase and decrease)? Also, would it work for the above scenario. Thanks in advance.
Why not? You could create one parent class with that properties and get inherited by child classes. Also you can create interface and implement custom logic for each class you want to have such property.
public class Parent
{
public int Increase { get; set; }
public int Decrease { get; set; }
}
public class Child1 : Parent
{
}
public class Child2 : Parent
{
}

Create class based on roles

I am developing a application for sports clubs administraion. And my problem is that I have one primary class Member which contains all the "default" information (name, surname, gender...) and two other classes Coach and Practitioner which inherit from Member. A coach has some specific properties (salary, trainings held in current month...) wheres a practitioner has some others (isCompetitor, category ...)
The problem is that a Practitoner can also be a Trainer as well as the other way around. How can I model this into something that is better then having two entries for the same person?
Edit: this is how it looks now
Class Member {}
Class Coach:Member {}
Class Practitioner:Member {}
You can create one class 'member' that contains a list of roles. Each role (coach and/or practitioner) inherit from a base class 'role' which contains all properties you now have in your member class. Coach and practitioner than have their own specific properties. So:
public class Member {
public IList<Role> Roles { get; private set; }
public Member(){
Roles = new List<Role>();
}
}
public class Role {
public string SomeGlobalProperty { get; set; }
}
public class Coach : Role {
public string SomeSpecificProperty { get; set; }
}
public class Practitioner : Role {
public string SomeSpecificProperty { get; set; }
}
If you're only looking at them in one way at a time - so as one of a group of practitioners, or as one of a group of trainers - then you can create them as the specific type of member they are being viewed as at a time. If required, you can add a boolean property "IsTrainer" to practitioner and "IsPractitioner" to trainer, to indicate that there is more info about that person elsewhere.
This presumes you're only looking at them in one way at a time, and not getting a page with all info about the person.
SImeple: Realize that you basiaclly need to read an intro book into OOP.
A Member is a Member (and even that is disputable - acutally it is a Party, regardless of what it does).
It has different roles which are basically a collection of roles, all with start and end date.
Party
CoachInformation
PractitionerInformation
etc.
I suggest reading "The Data Model Resource Book", volume 1 - they go into great detail about this standard problem and how most people get it wrong.

Can someone explain the exact use of interfaces in C#?

Can someone explain the exact use of interfaces in C#?
Has msdn not been helpful on this?
http://msdn.microsoft.com/en-us/library/87d83y5b.aspx
This has been discussed so many times here in the past that it is hard to pick any one duplicate for this question.
To save the time of repeating what has been said before, try this search, and start going through the results.
Imagine the the situation of having a factory that creates cars. You know that every vehicle has an engine and can be started, so you have the following:
interface IVehicle
{
Engine vehicleEngine { get; set; }
bool StartEngine();
}
Now, the factory makes an array of other vehicles, so for instance a truck and a normal car:
public Car : IVehicle
{
// MUST implement vehicleEngine and StartEngine:
public Engine vehicleEngine { get; set; }
public bool StartEngine()
{
// Cars needs to do xyz to start
}
public int MaxNumberOfPassenger { get; set; } // Specific to Car
}
and then:
public Truck : IVehicle
{
// MUST implement vehicleEngine and StartEngine:
public Engine vehicleEngine { get; set; }
public bool StartEngine()
{
// Trucks needs to do abc to start
}
public int MaximumLoad { get; set; } // Specific to Truck
}
This therefore forces all vehicles to implement specific members to fall under the category of a vehicle, but then can also be specialized with their own distinct members.
In the most simple terms, an Interface expresses what one, or more classes can do, although the implimentation may vary across the various classes.
Polymorphism
You can use 2 classes that implement the same interface without having to know exactly which concrete class it is. It aids in keeping code loosely coupled.
An interface defines the minimum requirements that a class that can be instantiated must implement. It expresses this through methods.
For instance, an interface could define a function called Foo which takes an integer and returns a boolean:
public interface ICanFoo
{
bool Foo(int number);
}
Any class which implements this interface must also implement this method:
public class Fooable : ICanFoo
{
public bool Foo(int number)
{
// do something
}
}
The implementation within the method is up to the specific classes which are implementing the interface.
By using interfaces you no longer care about implementation are compile time, but rather specification. You can call it like this:
ICanFoo myFooable = ...
bool success = fooable.Foo(4);
The actual type of fooable can be any class that implements ICanFoo since you know that ICanFoo will always define a method implementation for the Foo method.

How To Implement Shared Behavior Between Classes (Without Multiple Inheritance Of Course) in C#

UPDATE:
So pretty much everyone here has told me that I just need to start all over again on how I designed my classes (thank you folks for your excellent answers by the way!). Taking the hint, I started doing extensive reading on the strategy pattern. I want to create behavior classes (or strategy classes) that inherit from an abstract base class or classes. The Candidate class would then have properties w/ the different abstract base class/classes as the Type for the behaviors or strategies. maybe something like this:
public abstract class SalaryStrategy {
public abstract decimal Salary { get; set; }
public abstract decimal Min { get; set; }
public abstract decimal Mid { get; set; }
public decimal CompaRatio {
get {
if (this.Mid == 0) { return 0; }
else { return this.Salary / this.Mid; }
}
}
}
public class InternalCurrentSalaryStrategy {
public override decimal Salary { get; set; }
public override decimal Min {
get { return this.Salary * .25m; }
set { }
}
public override decimal Mid { get; set; }
}
public class Candidate {
public int Id { get; set; }
public string Name { get; set; }
public SalaryStrategy CurrentSalaryStrategy { get; set; }
}
public static void Main(string[] args) {
var internal = new Candidate();
internal.CurrentSalaryStrategy = new InternalCurrentSalaryStrategy();
var internalElp = new Candidate();
internalElp.CurrentSalaryStrategy = new InternalCurrentSalaryStrategy();
var elp = new Candidate();
// elp.CurrentSalaryStrategy can stay null cause it's not used for elps
}
Any comments or suggestions?
ORIGINAL Question:
I am trying to learn and become more proficient at design patterns and principles. I have am currently working on a design for few classes that has stumped me. Here's a very condensed version of the code:
public class Candidate {
public int Id { get; set; }
public string Comments { get; set; }
// lots more properties and behaviors...
}
public class InternalCandidate : Candidate {
public decimal CurrentMid { get; set; }
public decimal CurrentMax {
get { return this.CurrentMin * 1.3m;
}
// lots more properties and behaviors...
}
public class EntryLevelCandidate : Candidate {
public string Gpa { get; set; }
// lots more properties and behaviors...
}
public class InternalEntryLevelCandidate /* what do I inherit here??? */ {
// needs all of the properties and behaviors of
// EntryLevelCandidate but also needs the CurrentMin and
// CurrentMax (and possibly more) in InternalCandidate
}
The InternalEntryLevelCandidate class is primarily an EntryLevelCandidate but needs to share some of the implementations of InternalCandidate. I say implementations because I don't want the implementations to be different or repeated, otherwise I would use an interface for common contracts and have concrete implementations in each class. Some of the implementations of the InternalCandidate properties and behaviors need to be common or shared. I have read about C++ and Ruby mixins, which seem to be something similar to what I want to do. I also read this interesting blog post that discusses an idea for a behavior type where a class would be able to inherit multiple behaviors while still maintaining a single "is a" relationship: http://www.deftflux.net/blog/post/A-good-design-for-multiple-implementation-inheritance.aspx. This seems to convey what I am wanting. Can anyone give me some direction on how I can accomplish this using good design practices?
Immutable data value classes. If any properties in your various Candidate subclasses represent some kind of meaningful data value, create an immutable class for it, with the behaviors you need. Each of your distinct Candidate subclasses can then use the data type, but your code is still encapsulated in the data classes.
Extension methods. These could be overloaded to work with any classes.
I'd avoid the decorator pattern and stick with compiled/reflectable functionality.
Composition. Develop the unique behaviors in separate classes right away, and build your Candidate classes around them, rather than writing unique behaviors in your Candidate classes and trying to pull out their functionality for use in related classes later.
Depending on how you use the classes, you could also implement and make use of explicit and implicit conversion operators to a related type, so instead of reimplementing interfaces (which you wanted to avoid), you could actually cast your object into the type/implementation you need for whatever purpose.
Another thing I just thought of, related to that last paragraph, is to have a leasing system, where your class spawns and object of the appropriate type, allows it to be manipulated, then consumes it later to assimilate the updated information.
Here's a scholarly paper on the subject that I think is pretty interesting (PDF link).
But, I think you are trying to impose business logic in your generalizations. You happen to know that an InternalCandidate will never have his GPA looked at. But, an InternalCandidate certainly has a GPA. So, you have cracked out this strange guy called an InternalEntryLevelCandidate because you happen to know that you want to look at this guy's GPA. Architecturally, I think the EntryLevelCandidate is incorrect. I would add a "Level" concept to a Candidate and give him a GPA. It's up to the business logic to decide if they look at the GPA or not.
Edit: Also, Scott Meyers does a great job of dissecting this issue in his books.
Disclaimer:
In my experience needing multiple inheritance is the exception rather than the rule, careful design of class hierarchies can usually avoid needing this feature. I agree with JP that this requirement could be avoided in your sample.
Back to the question, there is no clean solution, however you have a few options:
Use extension methods, has the disadvantage that right click Resolve does not works, also some people really dislike these puppies.
Create an aggregate object that holds and instance of each class you want composited, re-implement stub methods that delegate.
Define an interface for each behavior and have the methods in the base check if this is IInterface before executing the behavior. (allows you to pull behavior definitions to the base)
Near duplicate:
Multiple inheritance in C#
I agree that inheritance doesn't seem to be the right thing here. I'm not sure that I know the perfect answer, but perhaps the Decorator pattern is appropriate.
Another, more esoteric idea is to think about aspect-oriented programming. You can do some pretty amazing things with aspects, but it's a very advanced topic that I still haven't mastered. The kind of folks who have are like Rikard Oberg and his Qi4J cohorts.
I'd just use the Delegation pattern. Ultimately I'd use an interface for each distinct piece of functionality, then have a concrete class as a delegate for each interface. Then your final classes just use the delegates they need and can inherit from multiple interfaces.
public class InternalEntryLevelCandidate : EntryLevelCandidate {
private InternalCandidate internalCandidateDelegate
= new InternalCandidate();
public decimal CurrentMid {
get { return internalCandidateDelegate.CurrentMid; }
set { internalCandidateDelegate.CurrentMid = value; }
}
public decimal CurrentMax {
get { return internalCandidateDelegate.CurrentMax }
}
}

Categories