Showing posts with label design pattern. Show all posts
Showing posts with label design pattern. Show all posts

Thursday, July 17, 2014

Decorator Pattern in Java

This is the story of "Sam, the billionaire". I like to translate all my stories in Java. So, you will also see Java version of this story.
Story begins...
Sam is owner of a Toy Company. Dolls made in his company are very famous.
Some of the popular Dolls














                                                                                                                                                                   
Java version-
Sam defines an interface Doll which defines all required features which a doll should have (make, price & description).
Whenever a new type of doll is introduced it implements Doll interface. And it has to implement all the methods defined in it.






















                                                                                                                                                                   
Next Step...

To take his company a step forward he wants to introduce new features in his dolls.
  • Speech - Speaking doll, Singing doll, Nursery rhymes doll etc.
  • Motion - Walking doll, Running doll, Spinning doll etc.
  • Light - Doll with glowing eyes, mouth etc.
But he wants to keep these features customizable. Customer can choose one or more of these features and get a customized doll.

Sam decides to start making the dolls. So, he tries to figure out what all combinations are possible-
  1. Baby girl
  2. Baby girl which cries
  3. Baby girl which sings
  4. Baby girl which sings nursery rhymes
  5. Baby girl which walks
  6. Baby girl which cries and walks
  7. ...... And many more
Ok so, there are many possible combinations.
                                                                                                                                                                   
Java Version
To implement dolls with customizable features first thing that came into Sam's mind was inheritance. He made a class for each doll type which will implement Doll interface. Apart from implementing methods in Doll interface it added methods to give additional functionality specific to doll. 
e.g. SpeakingDoll class will implement Doll interface and will have addSpeech() method for additional functionality which will be called from make() method.

Class Diagram will look something like this.(Note- Not showing all classes due to space constraint)

There is a class explosion. Maintaining such a thing is going to be a big overhead.
                                                                                                                                                                  
Problems..

Large no. of possible combinations. So, many dolls will have to be built and Sam is not sure all of them will be sold.

Class Explosion. Large number of classes will make the code difficult to maintain.

If a new feature has to be added in future e.g. multiple languages again there will be a lot of possible combinations.

Not all functionality can be foreseen, If a new feature is added in future new classes will be required.

If we have to change voice of speaking dolls all dolls with speech will have to be changed.

Any change in the existing functionality will impact many classes.

                                                                                                                                                                   
Finding the Solution...

He calls his team for a solution. Luckily one of the team member suggests a perfect solution.

Use of Decorator Pattern.

Lets try to understand this solution-
Make a doll when there is an order. Take the basic doll e.g. Baby girl, Baby boy etc. based on the requirement and add features to it as per client's demand.

Add features dynamically at runtime.

Lets take example of Singing baby girl to understand the solution. 
Baby girl doll is build in factory. Sound Engineer use this doll and add singing feature to it.
If any other feature is also required e.g. walking then this doll is passed to the motion engineer who adds the feature on the doll. So, one feature is built on the top of the other. Something like this.
                                                                                                                                                                   
JavaVersion-
As each feature has to be added at runtime we need a separate class for each feature e.g. SingingDoll with method addSinging() which will add the required feature.

Sound engineer required a baby girl doll to add singing feature on it similarly SingingDoll object needs BabyGirl object on the top of which it can add singing feature.
SingingDoll has BabyGirl
  • Using composition we can add additional features to an object. 
In future requirement can change and client may want Baby boy doll or any other doll with singing feature. If we add an object of type Doll to SingingDoll we will not have to worry about the type of doll as all dolls implement Doll interface.
So, we can decide at runtime what type of doll we want and can add its object to SingingDoll
  • Using inheritance we can change the type of an object at runtime.
So, using the power of composition and inheritance together we can add the functionality dynamically. Any feature class will look like this.

Works well for SingingDoll but in future we may want to add another feature on the top of it e.g. Crying

Design will be something like this in that case-

In that case, we will need CryingDoll class to wrap around object of SingingDoll class. i.e.
CryingDoll has SingingDoll. Singing Doll has BabyGirlDoll.
Like any Feature class CryingDoll class has object of type Doll. But we have to add SingingDoll object(another Feature).
If SingingDoll too implements Doll interface it will not be a problem.

If Feature class implements Doll interface we can add any Feature on the top of the other.

Now doll object in Feature class can be used to access the basic functionality of underlying object and any new feature can be added before or after it.

To make design more flexible we add a superclass FeatureDecorator which all feature classes will extend. Any additional behaviour can be added in subclass.

This is example of Decorator Pattern in Java.

  • To add feature to a component at runtime Decorator class is used.
  • This class implements interface of the component and also has object having type of component's interface.
  • So, object of any component can be added to a Decorator.
  • Since Decorator also implements component's interface, one Decorator can also be added to other.
This is how Decorator Pattern works.
Decorator object has another Decorator object or Component object.
Component object is at the core.













  • Client has access to the outermost Decorator object.
  • Decorator object have full access to the functionality of underlying Decorator or Component. Using its object it can call the functionality before or after its own functionality. This helps in adding or modifying underlying functionality.
This is how method call works in Decorator Pattern-













Client calls the method of outermost Decorator class. This method calls the method of underlying Decorator/Component using the object it has. It can use output of this method to add some additional behaviour to it.

Using this lets try to calculate the cost of a Singing Baby Doll-
Outermost Object is SingingDoll(Decorator). From cost() method of SingingDoll we can call doll.cost(). This will give cost of underlying doll object which is actually BabyDoll(Component). Now we can add additional cost of singing feature and return to the user.

Now that our pattern is ready its time to write some Java Code-
Main Interface-











Main components (Types of Dolls)-
It implements Doll interface and its methods.

BabyGirl implementation-













BabyBoy implementation-














Abstract Decorator class-
It was simple till this point. Now we need to add Decorator superclass so that we can add features dynamically.















This interface has an object of type Doll and it also implements Doll interface.

ConcreteDecorator class-

SingingDoll class extends this class.



Methods of SingingDoll calls method of doll object and add its own functionality before or after it.

Here functionality added by SingingDoll class is outlined in green color in each method.

SingingDoll object gets access to the underlying doll object functionality and state. It can add or modify it as per requirement.








Lets use this code to create a Singing Baby Girl doll.














Create object of BabyGirl and pass it to SingingDoll object.

output of singing.make()-
Baby Girl is Ready
Singing feature added

We call make method of SingingDoll from which make method of underlying doll object(BabyGirl) is called.

Similarly, when we call cost() method we get cost of BabyGirl (100)+Singing(50)
150

If we change the underlying object to BabyBoy-














Methods of BabyBoy will be called.
output of singing.make()-
Baby Boy is Ready
Singing feature added
when we call cost() method we get cost of BabyBoy (60)+Singing(50)
110

To add any new feature e.g. Crying to it Just need to pass singing object to the constructor of Crying class(which extends FeatureDecorator)
We can add as many features as we want. We can also have different types of decorators e.g. SpeechDecorator, MotionDecorator, LightDecorator etc.
But they should follow rules of Decorator pattern-

  • Decorator class should be of same type as the component to which they add functionality. So, they implement the interface which the component implement.
  • Decorator class wrap the object of the component and add functionality to it. So, they have an object of the component. Type of this object is Interface which component implement. This provide flexibility to add another Decorator on top (as all Decorators are also of same type)
  • There can be many layers of Decorator wrapped around component. Each Decorator add or modify the existing functionality.
  • Methods of Decorator call methods of component (using the object they have) either before or after their implementation. This adds or modifies the functionality.

Class Diagram of Decorator Pattern-


Decorator Pattern is a complicated pattern so it should be used wisely else it makes the code hard to understand and maintain.
In Java, I/O Stream uses Decorator Pattern.

Thanks to Decorator Pattern, Sam is a billionaire today.

















visit ApexInformatix.com for Online/Classroom course on Java and other technologies

Tuesday, April 15, 2014

Factory Pattern in Java


Harry works at take away counter of a food joint.


What is Harry’s job?
  1. He takes an order
  2. Passes a slip back in kitchen with order no. and food item on it
  3. Gets back a food package from kitchen with order no. on it
  4. Announce the order no.
  5. Take payment and give order and bill to customer

It’s a simple job and Harry is good at it.
Why?
Because he does not have to worry what’s going on in kitchen. How is food being prepared? What is the recipe? What if there are no tomatoes and chef has to put tomato puree instead? He doesn’t have to deal with all these problems.
So, the creation of food item is hidden from him. Hiding the food creation part from Harry has made his job very simple. Just imagine if he has to prepare the food himself too. How complicated it will get for him?

Nice story but how is it related to Java or Factory pattern in java?


To understand it lets translate it into java-


serviceCustomer()  in above code is a simple method with all the logic from taking the order to delivering it.
It has following parts-
  1. generate order no.
  2. Prepare food item
  3. generate bill
  4. announce order no.
  5. deliver order
Logic to prepare food item is marked as Creation logic.
Based on the food ordered, say Pizza. Object of the class is created 
Pizza pizza = new Pizza();
Some work on the object is done-
pizza.addCheese();
pizza.addTopping();

What's the problem with this?

This creation logic is based on the food item ordered. To keep it simple we have only shown it for Pizza and Burger but imagine how big this logic will be for complete menu. And code will be very hard to maintain.

Imagine if a new item is added to the menu this code will have to be changed. The method will have to be tested again. And if some careless coder makes a mistake. All the customers will get impacted as serviceCustomer method has the bug. 

Solution-
Let's go back to the Take Away Counter example we discussed in the beginning. 
If you see the tasks being done in serviceCustomer() method again-

  1. generate order no.
  2. Prepare food item
  3. generate bill
  4. announce order no.
  5. deliver order
Harry was doing everything highlighted in Green

Why was Harry's job so simple?

Because he didn't have to worry about the preparation of food items.(Point 2)
So if we take out this part from serviceCustomer() the method will become perfect like Harry's job.

But where will this task go?
In the Kitchen of course that's where all the food is prepared.


















Creation logic has been transferred to Kitchen class. Now serviceCustomer() looks much simple and manageable.



















You may be wondering, why we created a separate class when we could have just created a separate method getFoodItems in TakeAwayCounter.
TakeAwayCounter is just one client of getFoodItems.But it can be used by other classes(clients). Say for example HomeDeliveryCounter or ServiceCounter.
Basic idea of separating the logic in a separate class Kitchen is to keep all these clients which are now using getFoodItems or any future client free from any impact due to change in creation logic.

By creating Kitchen class we have succeeded in separating the creation logic. Kitchen here is an example of java factory.

  • Java Factory hides the creation logic from client


Kitchen is of no use if food is not sent back to the customer and is lying in the Kitchen itself.
So, we also have to return the food item object example Pizza or Burger to the calling method.
Harry never knew what used to be inside the food package. For him every food item used to come inside a food package. Similarly Factory in java returns every object casted under the cover of interface.

As we know a method can return only one type. So, how can different types (Pizza Burger) returned from same method.
Answer is inheritance.

Pizza and Burger Implements FoodParcel interface so, getItems return FoodParcel. Any new food item will have to inherit FoodParcel.

Another important point about java factory is-

  •  Returns object casted as Interface.
This is how the complete thing will work in java-
  • FoodParcel is our Interface. 
  • All food items implement it.(Pizza, Burger)
  • TakeAwayCounter is a client which need an object of food items(Pizza, Burger)
  • Kitchen is our factory which creates Object of food items. Cast them as FoodParcel and return to the client.




















Factory Pattern in Java-




















This is how it works-

  1. Creation logic is hidden in Factory
  2. All products implements AbstractProduct interface
  3. Client requests for an object from factory
  4. Factory creates object of type Product(Concrete) and cast it to AbstractProduct(Interface)
  5. Client uses the object cast as AbstractProduct
  6. As this pattern is a solution for object creation so, this comes under type Creational Patterns

visit ApexInformatix.com for Online/Classroom course on Java and other technologies