I'm having difficulties deciding when I should be subclassing instead of just adding an instance variable that represents different modes of the class and then let the methods of the class act according to the selected mode.
For example, say I've a base car class. In my program I'll deal with three different types of cars. Race cars, busses and family models. Each will have their own implementation of gears, how they turn and seat setup. Should I subclass my car into the three different models or should I create a type variable and make the gears, turning and seating generic so they would act different depending on which car type was selected?
In my current situation I'm working on a game, and I've come to realise that it's starting to get a bit messy, so I ask advice on possibly refactoring of my current code. Basically there are different maps, and each map can be one of three modes. Depending on which mode the map is defined as there will be different behaviour and the map will be built in a different way. In one mode I might have to give out rentals to players and spawn creatures on a timeout basis, wherein another the player is responsable for spawning the creatures and yet in another there might be some automated spawned creatures alongside with player spawned ones and players constructing buildings. So I'm wondering whether it would be best to have a base map class, and then subclass it into each of the different modes, or whether to continue down my current path of adding differentiated behaviour depending on what the map type variable is set to.
All credits to AtmaWeapon of http://www.xtremevbtalk.com answering in this thread (Archive Link)
Core to both situations is what I feel is the fundamental rule of object-oriented design: the Single Responsibility Principle. Two ways to express it are:
"A class should have one, and only one, reason to change."
"A class should have one, and only one, responsibility."
SRP is an ideal that can't always be met, and following this principle is hard. I tend to shoot for "A class should have as few responsibilities as possible." Our brains are very good at convincing us that a very complicated single class is less complicated than several very simple classes. I have started doing my best to write smaller classes lately, and I've experienced a significant decrease in the number of errors in my code. Give it a shot for a few projects before dismissing it.
I first propose that instead of starting the design by creating a map base class and three child classes, start with a design that separates the unique behaviors of each map into a secondary class that represents generic "map behavior". This post is concerned with proving this approach is superior. It is hard for me to be specific without a fairly intimate knowledge of your code, but I'll use a very simple notion of a map:
Public Class Map
Public ReadOnly Property MapType As MapType
Public Sub Load(mapType)
Public Sub Start()
End Class
MapType indicates which of the three map types the map represents. When you want to change the map type, you call Load() with the map type you want to use; this does whatever it needs to do to clear the current map state, reset the background, etc. After a map is loaded, Start() is called. If the map has any behaviors like "spawn monster x every y seconds", Start() is responsible for configuring those behaviors.
This is what you have now, and you are wise to think it's a bad idea. Since I mentioned SRP, let's count the responsibilities of Map.
It has to manage state information for all three map types. (3+ responsibilities*)
Load() has to understand how to clear the state for all three map types and how to set up the initial state for all three map types (6 responsibilities)
Start() has to know what to do for each map type. (3 responsibilities)
*Technically each variable is a responsibility but I have simplified it.
For the final total, what happens if you add a fourth map type? You have to add more state variables (1+ responsibilities), update Load() to be able to clear and initialize state (2 responsibilities), and update Start() to handle the new behavior (1 responsibility). So:
Number of Map responsibilities: 12+
Number of changes required for new map: 4+
There's other problems too. Odds are, several of the map types will have similar state information, so you'll share variables among the states. This makes it more likely that Load() will forget to set or clear a variable, since you might not remember that one map uses _foo for one purpose and another uses it for a different purpose entirely.
It's not easy to test this, either. Suppose you want to write a test for the scenario "When I create a 'spawn monsters' map, the map should spawn one new monster every five seconds." It's easy to discuss how you might test this: create the map, set its type, start it, wait a little bit longer than five seconds, and check the enemy count. However, our interface currently has no "enemy count" property. We could add it, but what if this is the only map that has an enemy count? If we add the property, we'll have a property that's invalid in 2/3 of the cases. It's also not very clear that we are testing the "spawn monsters" map without reading the test's code, since all tests will be testing the Map class.
You could certainly make Map an abstract base class, Start() MustOverride, and derive one new type for each type of map. Now, the responsibility of Load() is somewhere else, because an object can't replace itself with a different instance. You may as well make a factory class for this:
Class MapCreator
Public Function GetMap(mapType) As Map
End Class
Now our Map hierarchy might look something like this (only one derived map was defined for simplicity):
Public MustInherit Class Map
Public MustOverride Sub Start()
End Class
Public Class RentalMap
Inherits Map
Public Overrides Sub Start()
End Class
Load() isn't needed anymore for reasons already discussed. MapType is superfluous on a map because you can check the type of the object to see what it is (unless you have several types of RentalMap, then it becomes useful again.) Start() is overridden in each derived class, so you've moved the responsibilities of state management to individual classes. Let's do another SRP check:
Map base class
0 responsibilities
Map derived class
Must manage state (1)
Must perform some type-specific work (1)
Total: 2 responsibilities
Adding a new map
(Same as above) 2 responsibilities
Total number of per-class responsibilities: 2
Cost of adding a new map class: 2
This is much better. What about our test scenario? We're in better shape but still not quite right. We can get away with putting a "number of enemies" property on our derived class because each class is separate and we can cast to specific map types if we need specific information. Still, what if you have RentalMapSlow and RentalMapFast? You have to duplicate your tests for each of these classes, since each has different logic. So if you've got 4 tests and 12 different maps, you'll be writing and slightly tweaking 48 tests. How do we fix this?
What did we do when we made the derived classes? We identified the part of the class that was changing each time and pushed it down into sub-classes. What if, instead of subclasses, we created a separate MapBehavior class that we can swap in and out at will? Let's see what this might look like with one derived behavior:
Public Class Map
Public ReadOnly Property Behavior As MapBehavior
Public Sub SetBehavior(behavior)
Public Sub Start()
End Class
Public MustInherit Class MapBehavior
Public MustOverride Sub Start()
End Class
Public Class PlayerSpawnBehavior
Public Property EnemiesPerSpawn As Integer
Public Property MaximumNumberOfEnemies As Integer
Public ReadOnly Property NumberOfEnemies As Integer
Public Sub SpawnEnemy()
Public Sub Start()
End Class
Now using a map involves giving it a specific MapBehavior and calling Start(), which delegates to the behavior's Start(). All state information is in the behavior object, so the map doesn't really have to know anything about it. Still, what if you want a specific map type, it seems inconvenient to have to create a behavior then create a map, right? So you derive some classes:
Public Class PlayerSpawnMap
Public Sub New()
MyBase.New(New PlayerSpawnBehavior())
End Sub
End Class
That's it, one line of code for a new class. Want a hard player spawn map?
Public Class HardPlayerSpawnMap
Public Sub New()
' Base constructor must be first line so call a function that creates the behavior
MyBase.New(CreateBehavior())
End Sub
Private Function CreateBehavior() As MapBehavior
Dim myBehavior As New PlayerSpawnBehavior()
myBehavior.EnemiesPerSpawn = 10
myBehavior.MaximumNumberOfEnemies = 300
End Function
End Class
So, how is this different from having properties on derived classes? From a behavioral standpoint there's not much different. From a testing viewpoint, this is a major breakthrough. PlayerSpawnBehavior has its own set of tests. But since HardPlayerSpawnMap and PlayerSpawnMap both use PlayerSpawnBehavior, then if I've tested PlayerSpawnBehavior I don't have to write any behavior-related tests for a map that uses the behavior! Let's compare test scenarios.
In the "one class with a type parameter" case, if there are 3 difficulty levels for 3 behaviors, and each behavior has 10 tests, you'll be writing 90 tests (not including tests to see if going from each behavior to another works.) In the "derived classes" scenario, you'll have 9 classes that need 10 tests each: 90 tests. In the "behavior class" scenario, you'll write 10 tests for each behavior: 30 tests.
Here's the responsibility tally:
Map has 1 responsibility: keep track of a behavior.
Behavior has 2 responsibilities: maintain state and perform actions.
Total number of per-class responsibilities: 3
Cost of adding a new map class: 0 (reuse a behavior) or 2 (new behavior)
So, my opinion is that the "behavior class" scenario is no more difficult to write than the "derived classes" scenario, but it can significantly reduce the burden of testing. I've read about techniques like this and dismissed them as "too much trouble" for years and only recently realized their value. This is why I wrote nearly 10,000 characters to explain it and justify it.
You should subclass wherever your child type is some sort of specialization of the parent type. In other words, you should avoid inheritance if you just need functionality. As the Liskov Substitution Principle states: "if S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without altering any of the desirable properties of that program"
In your case i would go with a hybrid approach (this might be called composition, i don't know), where your map mode variable is actually a separate object that stores all related data/behavior to the map's mode. This way you can have as many modes as you like without actually doing too much to the Map class.
gutofb7 nailed it on the head as to when you want to subclass something. Giving a more concrete example: In your Car class, would it matter anywhere in your program what type of car you were dealing with it? now if you subclassed Map, how much code would you have to write that deals with specific subclasses?
In the particular problem you talked about with the maps and spawning, I think this is a case where you want to favour composition over inheritance. When you think about it, they aren't exactly three different types of map. Instead, they are the same map with three different strategies for spawning. So if possible, you should make the spawning function a separate class and have an instance of a spawning class as a member of your map. If all the other differences in "modes" for your maps are similar in nature, you might not have to subclass the map at all, although subclassing the different components (i.e. have a spawn_strategy base class and subclass the three types of spawning from that), or at least giving them a common interface, will probably be necessary.
Given your comment that each type of map is meant to be conceptually different, then I would suggest subclassing, as that seems to fulfill Liskov's substitution principle. However, that is not to say you should give up on composition entirely. For those properties which every type of map has, but may have different behaviour/implementation, you should consider making your base class have them as components. That way you can still mix and match functionality if you need to, while using inheritance to maintain a separation of concerns.
I don't program in C#, but in Ruby on Rails, Xcode, and Mootools (javascript OOP framework) the same question could be asked.
I don't like having a method that will never be used when a certain, permanent, property is the wrong one. Like if it's a VW Bug, certain gears will never be turned. That's silly.
If I find some methods like that I try to abstract everything out that can be shared among all my different "cars" into a parent class, with methods and properties to be used by every kind of car, and then define the sub classes with their specific methods.
Related
I want to call it a "Helper" but this seems way too general.
Let's say I have a class called WidgetCranker and WidgetCranker can be set up to crank out widgets of the type Square, Keyhole and GearShape. I can also specify which Color I want my widgets to be and which Label I want stamped on them.
Now, setting up each individual instance of WidgetCranker is fairly involved, the constructor just gives you an empty WidgetCranker and you have to manually set the type and colour of widgets you want to crank.
WidgetCranker keyholeWidget = new WidgetCranker();
keyholeWidget.Type = WidgetTypes.Keyhole;
keyholeWidget.Color = WidgetColors.Red;
keyholeWidget.Label = "ACME Industries Prototype 1";
But I have a class that requires a lot of WidgetCrankers that pretty much all look the same except for the label. I want to make my code more readable and less laborious to maintain, so I create a helper class that does all the lifting for me. So the above now becomes:
WidgetCranker keyholeWidget = WidgetCrankerHelper.RedKeyhole("ACME Industries Prototype 1");
My question is twofold:
Is this an actual design pattern and if so, what do we call it? I want to call it a factory, but it most definitely isn't a factory pattern. We're creating exactly the same kind of object in every case, just instantiating them differently. I know it's a type of "Helper", but I want to be more specific than that if I can. It's a helper that does a very specific thing.
Given that "Helper" is a very generic name, I feel that just naming the method by what it produces isn't enough. I should name it so that it's obvious what it does. So would MakeRedKeyhole be better or BuildRedKeyhole? I don't want to use GetRedKeyhole because that implies we're getting back a reference to an existing instance and not creating a brand new one.
I tend to stay away from the term "Helper" as all classes are supposed to be helpful, right? :)
I think that calling this either Factory or Builder would be acceptable. The point of abstract factory is to encapsulate the construction/instantiation of an object. It could return different types, but it doesn't need to. The type consuming the factory shouldn't care.
I tend to use the "Builder" name when it is doing any complex construction like this.
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.
So let's assume I have a class named ABC that will have a list of Point objects.
I need to make some drawing logic with them. Each one of those Point objects will have a Draw() method that will be called by the ABC class.
The Draw() method code will need info from ABC class.
I can only see two ways to make them have this info:
Having Abc class make public some properties that would allow draw() to make its decisions.
Having Abc class pass to draw() a class full of properties.
The properties in both cases would be the same, my question is what is preferred in this case. Maybe the second approach is more flexible? Maybe not? I don't see here a clear winner, but that sure has more to do with my inexperience than any other thing.
If there are other good approaches, feel free to share them.
Here are both cases:
class Abc1 {
public property a;
public property b;
public property c;
...
public property z;
public void method1();
...
public void methodn();
}
and here is approach 2:
class Abc2 {
//here we make take down all properties
public void method1();
...
public void methodn();
}
class Abc2MethodArgs {
//and we put them here. this class will be passed as argument to
//Point's draw() method!
public property a;
public property b;
public property c;
...
public property z;
}
Also, if there are any "formal" names for these two approaches, I'd like to know them so I can better choose the tags/thread name, so it's more useful for searching purposes. That or feel free to edit them.
The best approach depends on the nature of the information ABC needs to provide to the Point instances, the nature of the relationship between these classes, and the "expected" future for them. In other words there are a lot of qualitative factors.
If you do go with passing the Point an ABC instance, don't - rather, work out an appropriate abstraction for whatever it is Point needs from ABC, and encapsulate that in an interface. In static terms this is similar to simply creating a new class to encapsulate the information, but dynamically quite different.
The reason you shouldn't simply pass an instance of ABC is that it creates a circular dependency. Without going into too much detail, this should generally be regarded as a Very Bad Thing and avoided unless absolutely necessary.
And, at a more abstract level, it will make more sense and enable logical changes later if you identify the reason for this apparent circular dependency and factor that out - ie, create an interface to represent this 'data source for Points' role which ABC must fulfil. This role is distinct from the 'container for Points' role and that should be reflected in your design.
You could also pass the parameters to the draw() method - again this may be good or bad depending on a heap of factors. It's certainly not a Very Bad Thing, as long as you've thought about the implications.
It will be more work to create and maintain a separate class to pass state between ABC and point, but it's worth doing if you want to decouple point from ABC.
The main question is, how much does decoupling them matter to you, if it matters at all? If it makes sense in your domain for point instances to know about abc instances, it probably isn't worth creating the parameter class and you should just go with option 1.
Go with approach #2, but without the object. Just pass the parameters to Draw directly.
Since the Point class and ABC appear to have to mediate between themselves as to what to draw, why not call the draw() method on the Point, passing the actual ABC object as an argument. The ABC object can provide accessor methods (don't expose those properties!) and the point class (or subclass implementations) can decide what to call back on ABC for.
You may want to consider reversing the dependencies. Instead of Points accessing properties from ABC, have ABC set properties on the points when (or just before) calling "draw()" on each of them. Something similar to the Flyweight pattern used when rendering cells in Swing's JTables (see javadoc). You may also consider decoupling Point (data model) from PointDrawer (reusable rendering code). That way your Points will not depend on all those properties, only your PointDrawers will.
And yes, it is OO programming even if you explicitly pass in all parameters to each Point at drawing time - that way, Points have no dependency at all on either ABC or on ABC's would-be "parameter-passing class".