In my ASP.NET app, I have a Person and a PersonViewModel.
My Person was generated by LinqToSql. It has the properties that will be persisted in the database.
My PersonViewModel has everything Person has, plus a couple "select lists", which will be used to populate combo boxes, as well as a FormattedPhoneNumber (which is basically a PhoneNumber with dashes and parenthases added).
I originally just made Person a property on my PersonViewModel, but I was thinking that would mean the page would have to "know" whether something was a Person property or PersonViewModel property. For example, for name, the view would request pvm.Person.Name, but for the phone number, the view would request pvm.FormattedPhoneNumber. If I use inheritance, then everything the view needs would always be a direct property of the view model, hence pvm.Name.
This sounds great, but, there is no real "is-a" relationship here (i.e., I don't really think it makes sense to say "a PersonViewModel is a Person), and it seems to fly in the face of "preferring composition over inheritance". Still, I'm having difficulty thinking of a scenario where I'd need the ability to swap out a Person for something else. If I do this, it would no longer be a PersonViewModel.
What say you? Inherit from Person or keep Person as a property (or something else entirely)? Why?
Update
Thanks for all the answers.
It looks like the inheritance idea has been almost universally rejected, and for some sound reasons:
Decoupling the classes allows the ViewModel to contain only the properties from the domain model that are needed, plus any additional properties. With inheritance, you naturally expose all public properties from the domain model, which may not be a good idea.
The ViewModel doesn't automatically need to change just because the domain model changed.
As Jay mentioned, decoupling the ViewModel facilitates view-specific validation.
As Kieth mentioned, using a Mapper (such as AutoMapper) can eliminate a lot of the tedious work in mapping common properties between classes.
Deriving from an object implies an "is a" relationship. So in this case you would effectively be saying that a PersonViewModel is a Person. It seems that this is not likely to be the semantics that you really want to convey, so use composition instead of inheritance here.
In reality it probably doesn't really affect the maintainability of the application (other than having a few more dots here and there) but using composition certainly feels cleaner to me. In addition, if it's a PersonViewModel then presumably the view should know that that's the type it is dealing with.
Make Person a private member, and expose the properties that your view requires in the PersonViewModel, even if those properties just pass through the corresponding property of Person.
pvm.Person.Name is the code smell here.
Edit:
You're also limiting yourself to client-side validation and/or validation in the domain model, the latter meaning that if you create a second or subsequent ViewModel for Person, you can't change the validation on Person's members. (Well, you could, but this is a violation of the open-closed principle and you're introducing view concerns into the domain.) By hiding your domain objects from the view, you give yourself a clean space to perform use-case-specific validation before changes get made to your domain object. The domain object may have its own set of validators, but they can be strictly domain-appropriate, without view-specific issues creeping in.
You should not inherit from Person or use composition to have Person on PersonViewModel. Instead you should add the properties that you need to the PersonViewModel and map between them. Tools like AutoMapper (http://www.codeplex.com/AutoMapper) make this dead simple.
You should not expose your domain model directly to the View for a number of reasons, including security (under-posting and over-posting).
I am thinking a partial class may be better here. keep the generated Person class and add anothe partial Person class with the extra stuff in it.
On the one hand:
What if you did this?
Person p = new PersonViewModel { //init some properties };
Would p do everything you'd expect a Person to do? If it would, then sure, use inheritance. If it would have some peculiarities related to the fact that it's really a PersonViewModel, and not a Person, then use composition.
On the other hand:
My inclination is to use inheritance largely as a way of avoiding lots of duplicated code. Since you're only inheriting from one parent to one child (rather than to many children), you're not avoiding a lot of duplicated code in the first place. So it's probably not worth it to use inheritance.
One trick I've used, not specifically with ASP.NET MVC but with a similar use case, is to create a class that contains specifically those items specific to the ViewModel class (i.e., those that are not just tunneling through to the person class), and supplying an extension property on the Person class to allow access to the extended properties. This isn't strictly a ViewModel in the classic sense of the word, but I feel it allows for much of the same functionality without introducing awkward inheritance or code duplication with tunneled properties.
Here's a quick example of what I'm talking about:
public static class PersonExtensions {
public PersonViewData ViewData(this Person p) {
return new PersonViewData(p);
}
}
public class PersonViewData {
public PersonViewData(Person p) {
this._person = p;
}
private Person p;
public string FormattedPhoneNumber {
get { return p.PhoneNumber.ToPrettyString(); // or whatever }
}
}
Related
I am preparing for an interview and decided to brush up my OOP concepts.
There are hundreds of articles available, but it seems each describes them differently.
Some says
Abstraction is "the process of identifying common patterns that have
systematic variations; an abstraction represents the common pattern
and provides a means for specifying which variation to use" (Richard
Gabriel).
and is achieved through abstract classes.
Some other says
Abstraction means to show only the necessary details to the client of
the object
and
Let’s say you have a method "CalculateSalary" in your Employee class,
which takes EmployeeId as parameter and returns the salary of the
employee for the current month as an integer value. Now if someone
wants to use that method. He does not need to care about how Employee
object calculates the salary? An only thing he needs to be concern is
name of the method, its input parameters and format of resulting
member,
I googled again and again and none of the results seem to give me a proper answer.
Now, where does encapsulation fit in all these?
I searched and found a stack overflow question. Even the answers to that questions were confusing
Here, it says
Encapsulation is a strategy used as part of abstraction. Encapsulation
refers to the state of objects - objects encapsulate their state and
hide it from the outside; outside users of the class interact with it
through its methods, but cannot access the classes state directly. So
the class abstracts away the implementation details related to its
state.
And here another reputed member says,
They are different concepts.
Abstraction is the process of refining away all the
unneeded/unimportant attributes of an object and keep only the
characteristics best suitable for your domain.
Now I m messed up with the whole concept. I know about abstract class, inheritance, access specifiers and all. I just want to know how should I answer when I am asked about abstraction and/or encapsulation in an interview.
Please don't mark it as a duplicate. I know there are several similar questions. But I want to avoid the confusion among the conflicting explanations. Can anyone suggest a credible link? A link to stackoverflow question is also welcome unless it creates confusion again. :)
EDIT: I need answers, a bit c# oriented
Encapsulation: hiding data using getters and setters etc.
Abstraction: hiding implementation using abstract classes and interfaces etc.
Abstraction means to show only the necessary details to the client of the object
Actually that is encapsulation. also see the first part of the wikipedia article in order to not be confused by encapsulation and data hiding. http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)
keep in mind that by simply hiding all you class members 1:1 behind properties is not encapsulation at all. encapsulation is all about protecting invariants and hiding of implementation details.
here a good article about that.
http://blog.ploeh.dk/2012/11/27/Encapsulationofproperties/
also take a look at the articles linked in that article.
classes, properties and access modifiers are tools to provide encapsulation in c#.
you do encapsulation in order to reduce complexity.
Abstraction is "the process of identifying common patterns that have systematic variations; an abstraction represents the common pattern and provides a means for specifying which variation to use" (Richard Gabriel).
Yes, that is a good definition for abstraction.
They are different concepts.
Abstraction is the process of refining away all the unneeded/unimportant attributes of an object and keep only the characteristics best suitable for your domain.
Yes, they are different concepts. keep in mind that abstraction is actually the opposite of making an object suitable for YOUR domain ONLY. it is in order to make the object suitable for the domain in general!
if you have a actual problem and provide a specific solution, you can use abstraction to formalize a more generic solution that can also solve more problems that have the same common pattern. that way you can increase the re-usability for your components or use components made by other programmers that are made for the same domain, or even for different domains.
good examples are classes provided by the .net framework, for example list or collection. these are very abstract classes that you can use almost everywhere and in a lot of domains. Imagine if .net only implemented a EmployeeList class and a CompanyList that could only hold a list of employees and companies with specific properties. such classes would be useless in a lot of cases. and what a pain would it be if you had to re-implement the whole functionality for a CarList for example. So the "List" is ABSTRACTED away from Employee, Company and Car. The List by itself is an abstract concept that can be implemented by its own class.
Interfaces, abstract classes or inheritance and polymorphism are tools to provide abstraction in c#.
you do abstraction in order to provide reusability.
Image source
Abstraction: is shown in the top left and the top right images of the cat. The surgeon and the old lady designed (or visualized) the animal differently. In the same way, you would put different features in the Cat class, depending upon the need of the application. Every cat has a liver, bladder, heart, and lung, but if you need your cat to 'purr' only, you will abstract your application's cat to the design on top-left rather than the top-right.
Encapsulation: is demonstrated by the cat standing on the table. That's what everyone outside the cat should see the cat as. They need not worry whether the actual implementation of the cat is the top-left one or the top-right one, or even a combination of both.
Another detailed answer here.
I will try to demonstrate Encapsulation and Abstraction in a simple way.. Lets see..
The wrapping up of data and functions into a single unit (called
class) is known as encapsulation. Encapsulation containing and hiding
information about an object, such as internal data structures and
code.
Encapsulation is -
Hiding Complexity,
Binding Data and Function together,
Making Complicated Method's Private,
Making Instance Variable's Private,
Hiding Unnecessary Data and Functions from End User.
Encapsulation implements Abstraction.
And Abstraction is -
Showing Whats Necessary,
Data needs to abstract from End User,
Lets see an example-
The below Image shows a GUI of "Customer Details to be ADD-ed into a Database".
By looking at the Image we can say that we need a Customer Class.
Step - 1: What does my Customer Class needs?
i.e.
2 variables to store Customer Code and Customer Name.
1 Function to Add the Customer Code and Customer Name into Database.
namespace CustomerContent
{
public class Customer
{
public string CustomerCode = "";
public string CustomerName = "";
public void ADD()
{
//my DB code will go here
}
Now only ADD method wont work here alone.
Step -2: How will the validation work, ADD Function act?
We will need Database Connection code and Validation Code (Extra Methods).
public bool Validate()
{
//Granular Customer Code and Name
return true;
}
public bool CreateDBObject()
{
//DB Connection Code
return true;
}
class Program
{
static void main(String[] args)
{
CustomerComponent.Customer obj = new CustomerComponent.Customer;
obj.CustomerCode = "s001";
obj.CustomerName = "Mac";
obj.Validate();
obj.CreateDBObject();
obj.ADD();
}
}
Now there is no need of showing the Extra Methods(Validate(); CreateDBObject() [Complicated and Extra method] ) to the End User.End user only needs to see and know about Customer Code, Customer Name and ADD button which will ADD the record.. End User doesn't care about HOW it will ADD the Data to Database?.
Step -3: Private the extra and complicated methods which doesn't involves End User's Interaction.
So making those Complicated and Extra method as Private instead Public(i.e Hiding those methods) and deleting the obj.Validate(); obj.CreateDBObject(); from main in class Program we achieve Encapsulation.
In other words Simplifying Interface to End User is Encapsulation.
So now the complete code looks like as below -
namespace CustomerContent
{
public class Customer
{
public string CustomerCode = "";
public string CustomerName = "";
public void ADD()
{
//my DB code will go here
}
private bool Validate()
{
//Granular Customer Code and Name
return true;
}
private bool CreateDBObject()
{
//DB Connection Code
return true;
}
class Program
{
static void main(String[] args)
{
CustomerComponent.Customer obj = new CustomerComponent.Customer;
obj.CustomerCode = "s001";
obj.CustomerName = "Mac";
obj.ADD();
}
}
Summary :
Step -1: What does my Customer Class needs? is Abstraction.
Step -3: Step -3: Private the extra and complicated methods which doesn't involves End User's Interaction is Encapsulation.
P.S. - The code above is hard and fast.
UPDATE:
There is an video on this link to explain the sample:
What is the difference between Abstraction and Encapsulation
Below is a semester long course distilled in a few paragraphs.
Object-Oriented Analysis and Design (OOAD) is actually based on not just two but four principles. They are:
Abstraction: means that you only incorporate those features of an entity which are required in your application. So, if every bank account has an opening date but your application doesn't need to know an account's opening date, then you simply don't add the OpeningDate field in your Object-Oriented Design (of the BankAccount class). †Abstraction in OOAD has nothing to do with abstract classes in OOP.
Per the principle of Abstraction, your entities are an abstraction of what they are in the real world. This way, you design an abstraction of Bank Account down to only that level of detail that is needed by your application.
Inheritance: is more of a coding-trick than an actual principle. It saves you from re-writing those functionalities that you have written somewhere else. However, the thinking is that there must be a relation between the new code you are writing and the old code you are wanting to re-use. Otherwise, nobody prevents you from writing an Animal class which is inheriting from BankAccount, even if it is totally non-sensical.
Just like you may inherit your parents' wealth, you may inherit fields and methods from your parent class. So, taking everything that parent class has and then adding something more if need be, is inheritance. Don't go looking for inheritance in your Object Oriented Design. Inheritance will naturally present itself.
Polymorphism: is a consequence of inheritance. Inheriting a method from the parent is useful, but being able to modify a method if the situation demands, is polymorphism. You may implement a method in the subclass with exactly the same signature as in parent class so that when called, the method from child class is executed. This is the principle of Polymorphism.
Encapsulation: implies bundling the related functionality together and giving access to only the needful. Encapsulation is the basis of meaningful class designing in Object Oriented Design, by:
putting related data and methods together; and,
exposing only the pieces of data and methods relevant for functioning with external entities.
Another simplified answer is here.
† People who argue that "Abstraction of OOAD results in the abstract keyword of OOP"... Well that is incorrect.
Example: When you design a University in an application using object oriented principles, you only design an "abstraction" of the university. Even though there is usually one cash dispensing ATM in almost every university, you may not incorporate that fact if it's not needed for your application. And now though you have designed only an abstraction of the university, you are not required to put abstract in your class declaration. Your abstract design of university will be a normal class in your application.
I think they are slightly different concepts, but often they are applied together. Encapsulation is a technique for hiding implementation details from the caller, whereas abstraction is more a design philosophy involving creating objects that are analogous to familiar objects/processes, to aid understanding. Encapsulation is just one of many techniques that can be used to create an abstraction.
For example, take "windows". They are not really windows in the traditional sense, they are just graphical squares on the screen. But it's useful to think of them as windows. That's an abstraction.
If the "windows API" hides the details of how the text or graphics is physically rendered within the boundaries of a window, that's encapsulation.
my 2c
the purpose of encapsulation is to hide implementation details from the user of your class e.g. if you internally keep a std::list of items in your class and then decide that a std::vector would be more effective you can change this without the user caring. That said, the way you interact with the either stl container is thanks to abstraction, both the list and the vector can for instance be traversed in the same way using similar methods (iterators).
One example has always been brought up to me in the context of abstraction; the automatic vs. manual transmission on cars. The manual transmission hides some of the workings of changing gears, but you still have to clutch and shift as a driver. Automatic transmission encapsulates all the details of changing gears, i.e. hides it from you, and it is therefore a higher abstraction of the process of changing gears.
Encapsulation: Hiding implementation details (NOTE: data AND/OR methods) such that only what is sensibly readable/writable/usable by externals is accessible to them, everything else is "untouchable" directly.
Abstraction: This sometimes refers specifically to a type that cannot be instantiated and which provides a template for other types that can be, usually via subclassing. More generally "abstraction" refers to making/having something that is less detailed, less specific, less granular.
There is some similarity, overlap between the concepts but the best way to remember it is like this: Encapsulation is more about hiding the details, whereas abstraction is more about generalizing the details.
Abstraction and Encapsulation are confusing terms and dependent on each other.
Let's take it by an example:
public class Person
{
private int Id { get; set; }
private string Name { get; set; }
private string CustomName()
{
return "Name:- " + Name + " and Id is:- " + Id;
}
}
When you created Person class, you did encapsulation by writing properties and functions together(Id, Name, CustomName). You perform abstraction when you expose this class to client as
Person p = new Person();
p.CustomName();
Your client doesn't know anything about Id and Name in this function.
Now if, your client wants to know the last name as well without disturbing the function call. You do encapsulation by adding one more property into Person class like this.
public class Person
{
private int Id { get; set; }
private string Name { get; set; }
private string LastName {get; set;}
public string CustomName()
{
return "Name:- " + Name + " and Id is:- " + Id + "last name:- " + LastName;
}
}
Look, even after addding an extra property in class, your client doesn't know what you did to your code. This is where you did abstraction.
As I knowit, encapsulation is hiding data of classes in themselves, and only making it accessible via setters / getters, if they must be accessed from the outer world.
Abstraction is the class design for itself.
Means, how You create Your class tree, which methods are general ones, which are inherited, which can be overridden,which attributes are only on private level, or on protected, how Do You build up Your class inheritance tree, Do You use final classes, abtract classes, interface-implementation.
Abstraction is more placed the oo-design phase, while encapsulation also enrolls into developmnent-phase.
I think of it this way, encapsulation is hiding the way something gets done. This can be one or many actions.
Abstraction is related to "why" I am encapsulating it the first place.
I am basically telling the client "You don't need to know much about how I process the payment and calculate shipping, etc. I just want you to tell me you want to 'Checkout' and I will take care of the details for you."
This way I have encapsulated the details by generalizing (abstracting) into the Checkout request.
I really think that abstracting and encapsulation go together.
Abstraction
In Java, abstraction means hiding the information to the real world. It establishes the contract between the party to tell about “what should we do to make use of the service”.
Example, In API development, only abstracted information of the service has been revealed to the world rather the actual implementation. Interface in java can help achieve this concept very well.
Interface provides contract between the parties, example, producer and consumer. Producer produces the goods without letting know the consumer how the product is being made. But, through interface, Producer let all consumer know what product can buy. With the help of abstraction, producer can markets the product to their consumers.
Encapsulation:
Encapsulation is one level down of abstraction. Same product company try shielding information from each other production group. Example, if a company produce wine and chocolate, encapsulation helps shielding information how each product Is being made from each other.
If I have individual package one for wine and another one for
chocolate, and if all the classes are declared in the package as
default access modifier, we are giving package level encapsulation
for all classes.
Within a package, if we declare each class filed (member field) as
private and having a public method to access those fields, this way
giving class level encapsulation to those fields
Let's go back 6 million years,
Humans are not fully evolved. To begin with, evolution created a hole next to each body part to inject nutrients, which you can decide on yourself.
However, as humans get older, the nutrient requirements for each body part change Humans don't know which body parts need how much of which nutrient.
Evolution realised that exposing the hole next to each body part was a mistake, so it corrected it by encapsulating the entire body in skin and exposing only one opening, later it was called as "mouth."
Also, it abstracted the whole implementation of nutrient allocation through digestive system. All you have to do is keep eating through your mouth. The digestive system will take care of the body's nutrient composition changes to meet your needs.
In the software world, requirements will keep changing.
Encapsulating the internal data and exposing only the required functions will help with better maintenance. As a result, you have greater control over what occurs within your class/module/framework.
Abstraction makes it easier for the client to consume a class/module/framework. So clients don't have to do(know) 100 different steps to get the desired output. Exposed function/class will do all the work. In our example, you don't have to worry about which nutrients are required for which body part. Just eat it.
I've been experimenting with the decorator pattern to extend functionality of code you do not want to touch for example and I see how to implement it however I am now unsure why you don't just inherit from the original class and extend that way.
I have read that the decorator pattern allows you to add functionality at runtime whereas inheritance means its there at compile time.
I don't understand this.
Could someone explain this, provide examples and explain when its better to use decorator vs inheritance.
Thanks
Suppose you create a View class that displays your items in a certain way.
Now you decide you also want a version of it which is scrollable, so you create a ScrollableView which inherits the View.
Later you decide you also want a version with a border so you now need to make a BorderedView and a BorderdScrollableView.
If on the other hand you could make a decorator for each added styling. You would have the following classes:
View
ScrollableDecorator
BorderedDecorator
When you want a bordered scroll view you do:
new BorderedDecorator(new ScrollableDecorator(new View())).
So you can configure any combination of this with just the 3 classes. And you can add or remove them at runtime (suppose you click a button that says add border, you now wrap your view with a BorderDecorator ... while whith inheritance you need to implemented this view class if you haven't already, or you need to create a new view instance and copy all relevant data from the first view to the second view which is not as easy to do as just adding or removing wrappers).
Imagine a game like Civilization, where each square on the map can have a variety of resources attached to it (like, say, various ores, or wood, or oil, etc.).
If you used straight inheritance, you'd need to create a class for each kind of square. It'd be unwieldy to have
public class OilSquare {}
public class OilAndGoldSquare {}
public class GoldAndSilverSquare {}
// etc.
The Decorator Pattern allows one to mix and match without needing to create a rigid hierarchy. So, you'd have instead:
public class Square {}
public class GoldDec {}
public class SilverDec {}
public class OilDec {}
// ...
var crazyMix = new GoldDec(new SilverDec(new OilDec(new Square())));
Put another way, Decorators allow for the creation of pipeline behavior, with each step in the pipeline being swappable with another step.
As others have already said Decorators are good for adding "options" to things... The benefits come in the way you can chain methods etc. through the decorators.
Imagine I buy a car with options for leather interior, metallic paint and awesome spoiler...
There are 8 different combinations of the three options but with decorators you only need three extra classes.
The interesting thing though is the way the decorator pattern works. As a brief example:
public class MetallicPaint : Car
{
private Car car;
public MetallicPaint(Car wrappedCar)
{
car = wrappedCar;
}
public decimal Cost()
{
return car.Cost() + 500;
}
public string Description()
{
return car.Description() + ", Metallic Paint";
}
public string Speed()
{
return car.Speed();
}
[... {pass through other methods and properties to the car object}]
}
This isn't a complete example but highlights how the decorator can interact with the object it is decorating. And of course because it implements car it can be used just like a car in every other way (and passes through anything the decorator doesn't effect to the inner car object).
Of course if you had multiple of these decorators with a car nested inside each would in turn add their cost, their part of the description and maybe the spoiler would alter the speed whereas the others didn't...
In essence it allows you to modify an object in a much more modular and less fundamental way than inheritance would. Decorators should always be used as if they were the base object (in this case Car) so they should never expose any new methods or properties, just slightly change the effect of existing ones.
Decorator pattern is better than inheritance if you have many features to be added and you also require to have combination of these features. Suppose your base class is A, and you want to extend(decorate) this base class with feature f1,f2,f3,f4 and some combination of them like (f1,f2) and (f1,f3) and .. ; so you would require to create 4!=4*3*2*1=24 class in your hierarchy (4 for each feature and the rest for their combination). While, Using decorative pattern, you would only need to create 4 classes!
for #Seyed Morteza Mousavi in #Razvi post:
You are right, we can add two properties Scrollable and Bordered to View class, then check if the property is set to true so run the desired behaviour. But this requires that we already be aware of the number of the feature we require(which is not the case in decorator pattern). otherwise, with every new feature (say f1) we want to add to our class, we need to alter our main class, or inherit the main class (you would say) and add the property. Taking latter approach, you would further need to alter the part of the code which handles feature combination (this is not good, since it is not obeying the rule of thumb of "loose coupling!")
hope this helps.
If I were modelling various brands of cars would I use an inheritance hierarchy, or just varying constructor parameters?
What is the general rule for whether to relate objects using inheritance, or just by re-using the same class?
For cars I could just do something like new Car("Porsche","991","3.8") or I could have an overall abstract Car superclass, with abstract subclass manufacturers like "Porsche" and then possibly a class for each model of Porsche?
If you have a few properties that are shared by all cars (or methods that act on the object), and then unique properties (or methods) for each make/model, then you'd want to use inheritance. Otherwise, just varying instances are fine.
Let's just say you want these properties for all cars:
Make
Model
Year
Number of doors
In this case, you wouldn't want to create a class hierarchy, because it doesn't buy you anything.
Instead, if you had two "types" of cars: regular and race-car, and only the race-car could enable Nitrous Oxide (presumably a method that does this), you'd want a Car class, with RegularCar and RaceCar inheriting from it.
If you're just afraid of having to pass the same parameters to your constructor all the time, you can create static methods that call the constructor on your behalf. This is known as the Factory method pattern.
PS: my example really just came off the top of my head. But I hope you get the idea of what I'm trying to say :)
Creating subclasses is about managing complexity and splitting your problem into smaller and more simpler distinct and non overlapping cases. If you had to solve some problems for all the cars, and you think, this problem behave "specially" for Porsche because they have an extra backup engine that normal cars don't have, you could create something like
PorscheCar : Car
{
Engine engine;
Engine backupEngine;
}
NonPorscheCar : Car
{
Engine singleEngine;
}
So after you've decided to create a class that will solve a problem, if you detect multiple cases inside that problem, that you can, and decide to solve independently, you can create a subclass for each one of those. You can always solve every problem without using subclasses. The issue with that, is that I'll be a lot difficult to properly manage and organize the code if you don't create subclasses when you should create them.
You have to be careful to select what each problems each object or classes solve. If you want your Porsche to be printed like Porsche and normal cars without the *, it doesn't mean that Porsche "behaves" different, and you need to create a specific subclass. What actually behaves differently is how you print Porsche, so you should create something like:
Car
{
Brand brand;
}
CarPrinter
{
Car carToPrint;
static CreatePrinter(Car car)
{
return car.Brand() == PorscheBrand() ? new PorscheCarPrinter(car) : new DefaultCarPrinter(car);
}
}
PorscheCarPrinter
{
Print();
}
DefaultCarPrinter
{
Print();
}
So the problem that is splited into two cases is printing cars, not modeling cars per se.
In a more abstract way, you should create a class to model each concept of your domain. When you detect that the responsibility modeled and solved by a specific concept of that domain is complex, and you want to split it into smaller and distinct and non overlapping cases, then you should create a subclass for each of those smaller problems.
In your particular case, I don't know your entire problem, but it's highly unlikely you need to create subclasses for each brand of cars, since they are usually a single concept with just a single case to solve.
The problem with the single class approach is that you are stuck with the same instance variables and methods for all the different kinds of Cars.
For example, an Autobot might have a transform() method that most other cars would not have.
I mean, in theory you could define a transform() method for all Cars and have cars that don't support it throw an exception. But that's a much messier design than using inheritance.
Inheritance also gives you do fancy things like polymorphism. So for example, each car might have a parallelPark() method. But fancier cars might have an automated parallel parking mechanism that differs from all other cars. In that case, you simply override the parallelPark() method and Java will pick the right method.
I'd say that depends on how much logic is dependent on those properties like manufacturer and model. If it's none, it makes sense to do new Car("Porsche","991","3.8"), since the manufacturer and model are just properties. However, if the manufacturer and model define a single set of other properties, or of logic, then classes might make sense. That way instead of passing new Car("Porsche","991","3.8", gearingRatios, topSpeed, price, etc) every time you want a Porsche 991, you can just define a Porsche991 class that defines all of those properties.
Or, expanding more on the logic portion of it, if Porsche and Volkswagen cars would have very different logic in, say, the Accelerate() method, then instead of having one Accelerate() with a not-extensible switch/case method, you can use inheritance. Or if Porsches need a Race() method while Volkswagens do not, etc.
It's difficult to generalize this to a Car example without knowing how you plan on using the Car.
Take a look at the type object pattern (pdf).
For a superclass like cars, the more appropriate subclasses would be coupes, sedans, and convertibles. Car models should be a parameter.
I'm facing a design challenge that I just can't seem to solve in a satisfactory way. I've got a class library assembly that contains all of my shared ORM objects (using EntitySpaces framework). These objects are used in 2 or more different applications which is why they are in their own assembly. This setup has worked fine for 4+ years for me.
I also have a couple of applications built on the Composite Application Block (CAB) from Microsoft's Patterns & Practices group (P&P). Yes, I know this is really old but I'm a part time developer, one-man-shop and can't afford to update to whatever the current framework is.
Here is where my problem comes in: I have been exercising my OO design skills and whenever doing a substantial refactoring I try to shift from a procedural approach to a more OO approach. Of course a major aspect of OO design is placing the operations close to the data they work with, this means that my ORM objects need to have functionality added to them where appropriate. This is proving a real head scratcher when I also consider that I'm using P&P's Object Builder DI container within CAB and that much of the functionality I would move into my ORM objects will need access to the services exposed by my applications.
In other words, let's say I have a shared business object called "Person" (original, I know) and I have two applications that do ENTIRELY different things with a person. Application A provides a set of services that the Person object would need to have DI'ed in order for it to take on some of the methods that are currently littered throughout my services layers. Application B also has a different set of services that IT needs to have DI'ed into the person object.
Considering how the P&P Object Builder resolves dependencies using attribute decoration and Type reflection I don't see how I can accomplish this. In a nutshell, I have a shared object that when used in various applications I would need to inject dependencies so that it can perform certain operations specific to that application.
The only approach I can come up with is to inherit a new Type in Application A & B from the Person object. I would then add my non-shared functionality and DI code into this application-specific specialized Person object. Now that I write that it seems so obvious, however it's still my only solution I can come up with and I wanted to ask here to see if anyone else had a different solution they would like to propose?
One problem I would have with my solution is that I can see myself getting caught up on naming my inherited type - I mean... it's a person, so what else would you call it? Anyways, hopefully you will have some ideas for me.
Also, I'm not hip on the current technologies that are out there and really, to be honest only barely grasp the ones I'm currently using. So if I've said something contradictory or confusing I hope you can understand enough from the rest of the post to get what I'm asking.
It sounds like you're breaking the Single Responsibility Principle.
A Person object should just be holding the data for a person record. The services would then take in a Person object and manipulate it rather than having methods on the Person object that did that manipulation.
A classic example of this would be populating the Person object. Lets say app A grabs the data from a WebService, and app B grabs it from a database. In these cases I'd have some sort of Storage service that you call to get your Person object. Then implementation of that storage can be specific to each application, and be put into your IOC by the app, rather than trying to have a common interface in your shared assembly.
I agree with Cameron MacFarland on this: You are breaking SRP.
Of course a major aspect of OO design
is placing the operations close to the
data they work with, this means that
my ORM objects need to have
functionality added to them where
appropriate
Placing data AND functionality from A AND functionality from B is two responsibilities too much. Adhearing to SRP will almost always result in seperating data and functionality in seperate classes (data structures and objects). Thus, using Cameron MacFarlands sugestion is probably the best way to go.
I could think of couple of approaches to address this.
Separate out the behavior specific to each person/application separately. Perform dependency injection using setter in the application itself.
Apporach1
public interface IPerson
{
IPersonApp1 Person1 {get; set;}
IPersonApp2 person2 {get; set;}
}
class Person : IPerson
{
IPerson1 Person1 {get; set;}
IPerson2 Person2 {get; set;}
}
public interface IPerson1
{
// App1 specific behavior here
void App1SpecificMethod1();
}
class Person1: IPerson1
{
void App1SpecificMethod1()
{
// implementation
}
}
class App1
{
IPerson objPerson;
// Dependency injection using framework
App1(IPerson objPerson)
{
this.objPerson = objPerson;
// Dependency injection using setter
this.objPerson.Person1 = new Person1();
}
}
Separate out the behavior specific to each person/application separately. Perform dependency injection in the Person constructor.
Apporach2
class Person : IPerson
{
IPerson1 Person1 {get; private set;}
IPerson2 Person2 {get; private set;}
// DI through constructor. If the type IPerson1 or IPerson2 are not registered, it will be set to null.
Person(IPerson1 objPerson1, IPerson2 objPerson2)
{
this.Person1 = objPerson1;
this.Person2 = objPerson2;
}
}
Person interface project need to have reference to IPerson1 and IPerson2 or you can declare IPerson1 and IPerson2 in the Person interface project itself.
Let's say I have a POCO with the following:
[DataMember]
public Nullable<int> MetricId
{
get { return _metricId; }
set
{
if (_metricId != value)
{
_metricId = value;
OnPropertyChanged("MetricId");
}
}
}
private Nullable<int> _metricId;
I want to validate that the MetricId is strictly greater than 0
Obivously, if I put this rule as a data annotation in this class it will be overwritten the next time I regen the poco. Where do I put this logic?
Thanks!
I seem to remember the suggestion being to utilize partial classes and roll a partial class that implemented the logic you didn't want to be overwritten.
After reading the comments and responses, it seems that creating another class is fine, but by making it partial, it ties my business logic directly to the Entity Framework and the generated POCO code. This is worrisome because as EF4 changes into EF5 and the T4 template changes to the T5 template what will happen to my code? Plus I just don't feel comfortable using partial classes as normal classes.
Instead, and someone can still provide a better answer (please do), I think creating a framework independent object (one not tied to EF) is better. Then I can map it to a generic business object. Something like:
static Customer Map(CustomerPOCO poco)
{
return new Customer
{
CustomerId = poco.CustomerId
...
...
};
}
It's not clean using partial classes lets say you have product abstract lass and derived classes online product and store product. Both inherit price property but price is different. And let's say business logic may be different too. Now you got two additional classes that you don't really need. In larger system, it multiplies.