Structural Design Patterns - Adapter, Decorator, Composite, etc.
Want to refresh your understanding of Design Patterns, its types, usability, etc. first then you may like to refer to this article - Design Patterns >>
Structural Design Patterns
Design Patterns belonging to this category are used to combine classes and objects to form larger structures to suit your requirements. How do we actually achieve this? Class based structural design patterns use Inheritance to form larger structures whereas Object based structural design patterns use Composition for the same. The most popular structural design patterns are The Adapter Design Pattern, The Decorator Design Pattern, The Bridge Design Pattern, The Composite Design Pattern, The Proxy Design Pattern, The Facade Design Pattern, and The Flyweight Design Pattern.
We'll see Adapter, Decorator, and Composite Design Patterns in this article and discuss the other structural design patterns in subsequent articles. In this article we'll also see how the three design patterns (which look to be very similar) - Adapter, Decorator, and Composite differ from each other.
Adapter Design Pattern
As the name might suggest this design pattern is used where an unrelated class having a different interface is required to accept calls to the methods which are actually part of some other class having a different interface. How to do it? Well... there are the same two ways which we discussed above - using Interfaces and Composition. Suppose we have two classes A and B where we would like to have an instance of the type A to accept calls to the methods of class B then using inheritance we can derive a sub-class (say C) from A and add those methods of Class B into the new sub-class C so that they can be called on an instance of class C which will of course be of type A. Using composition we can simply have a new class which will have the original non-compliant class as a member and we'll add the required methods in this new class to internally call the corresponding methods of the non-compliant member class.
Example: Adapter Using Inheritance
class A{
public void methodA(int a){
...
}
...
}
class B{
public void methodB(){
...
}
...
}
class C extends class A{
public void methodB(){
...
int intValue = 5; //compute the actual int value
methodA(intValue);
}
...
}
Example: Adapter Using Composition
class A{
public void methodA(int a){
...
}
...
}
class B{
public void methodB(){
...
}
...
}
class C{
private A objectRefA;
...
public void methodB(){
int intValue = 5; //compute the actual int value
objectRefA.methodA(intValue);
}
...
}
Decorator Design Pattern
This design pattern is used to decorate the behavior of individual objects of a class without having to create a new derived class. It's normally used in UI design. Suppose there is a requirement where some of the instances of an UI component need a differnt look and feel (maybe based on the section of the screen they appear at or due to any other possible reason) then in such a case creating those many position-based derived classes of that UI component doesn't seem to be a good idea. Instead we can have a Decorator class having the basic look and feel and from it we can derive classed which will render those specific position-based look and feel. This will make the UI design more flexible by separating the actual UI component with its position-dependent look-n-feel. The same UI component can be used for all its occurrences with the corresponding decorator classes. Here the decorator classes will contain the actual UI component as a member and apply the area/position based look-n-feel logic on the contained instance(s).
class UIComp1{
...
}
class Decorator{
//...basic decoration of components
...
}
class DecoratorUIComp1Header extends Decorator{
//...Header specific decoration for UIComp1
...
}
Composite Design Pattern
This design pattern is used to make a composite of several primitive or composite member objects to have a common class which can accept calls intended to a variety of specialized objects (or cases). The composite children are normally termed as nodes and the primitives are called leaves. Example: suppose we need a common method which returns the specialized technical skills of an employee and all of its reportees (if the employee has any) then the Employee class may have a data structure (say a Vector) to store all the reportees which will themselves be instances of the Employee class only. Now we can have a common method getExpertise which will club the skills of the Employee which those of the reportees (if any) and return the clubbed data.
class Employee{
...
private String skill;
private Vector reportees;
...
public String getExpertise(){
String expertise = skill;
for(int i = 0; i < reportees.length; ++i)
expertise += ((Employee)reportees.elementAt(i)).getExpertise();
return expertise;
}
...
}
How do Adapters, Decorators and Composites differ?
Adapters may seem to decorate, but they are primarily used for enabling a class to accept calls belonging to a different interface. We have already sen above how inheritance and composition can be used to achieve this.
Decorators are not used to add different methods to all the instances instead they are used to add specific behavior to some specific instances. Though Adapters making use of composition may also be used here, but the intention is different here with what it's in case of a Adapter.
As discussed above, Composites are mainly used to provide a single interface to multiple instances which internally may have different structures depending on the values of the composed members in each of these instances. In the example discussed above we see that every Employee instance will invoke the same method 'getExpertise()' irespective of whether the instance represents a Employee having no reportees or the one who is having reportees (each of these reportees may themselves have their own reportees).
Liked the article? You may like to Subscribe to this blog for regular updates. You may also like to follow the blog to manage the bookmark easily and to tell the world that you enjoy GeekExplains. You can find the 'Followers' widget in the rightmost sidebar.
1 comment:
Nice overview of various popular design patterns. It can come handy while preparing for java interviews.
For more details, some readers may want to check Decorator design pattern
Post a Comment