Pages

Showing posts with label Design Pattern. Show all posts
Showing posts with label Design Pattern. Show all posts

Wednesday, 19 September 2012

Design Pattern - Adapter Pattern

What is it?

The adapter pattern can be described as follows. When you have to implement an interface, but you want to use another class’ (or interface’s) methods in order to implement it you are using the Adapter Pattern. An example will illustrate this much better than this definition.

Example Problem

Lets say I have an AddressBook, and I wish to display this AddressBook to a JTable. One solution (without using the Adapter Pattern) is to have my AddressBook implement the TableModel. This is not such a good idea, because I don’t want my AddressBook class (or object model) to be tied to Swing.

Solution (design)

I can provide a nice solution to this problem by using the Adapter Pattern. Instead of implementing the TableModel directly on the AddressBook, I instead create an intermediary adapter class. This adapter class actually uses the AddressBook methods in order implement the TableModel. So I would call this class the AddressBookTableAdapter. Review the code snippets below to get an idea of how this is implemented.
There is no need for an Adapter to subclass the AddressBook class. In fact, you should use the Delegation Pattern, instead of using subclass. The example below uses the Delegation Pattern instead of subclassing.

Code

 1: //AddressBook
 2: public class AddressBook{
 3:     List personList;
 4:
 5:     public int getSize(){…}
 6:     public int addPerson(…){…}
 7:     public Person getPerson(…){…}
 8:
 9: }
 1: //AddressBookTableAdapter
 2: public class AddressBookTableAdapter
 3: implements TableModel
 4: {
 5:      AddressBook ab;
 6:      public AddressBookTableAdapter( AddressBook ab ){
 7:         this.ab = ab;
 8:      }
 9:
 10:      //TableModel impl
 11:      public getRowCount(){
 12:          ab.getSize();
 13:      }
 14:
 15: }
 1: //Test
 2: public class Test{
 3:      public static void main( String[] args ){
 4:          AddressBook ab = //get reference to AddressBook somehow
 5:          AddressBookTableAdaptermodel =
 6:              new AddressBookTableAdapter( ab );
 7:          JTable table = new JTable( model );
 8:      }
 9: }

Why?

Now that you have seen the Adapter pattern, you ask why use it? Well, the answer to this question has already been provided in the example problem definition. You don’t want your object models implementing JavaVM specific interfaces becuase they might change in the future. Also, by implementing Swing interfaces directly into your object models, you make your code messy by introducing Swing event handling code there.
It’s a better idea to use the Adapter pattern. It will make it so that you can get the most out of your object model by limiting direct dependencies on interfaces (and perhaps classes) that you can’t control.

Design Pattern - Delegation Pattern

What is it?

Chances are if you have used AWT1.1 or Swing, you have already used the delegation pattern, you just didn’t know you were doing it. The delegation pattern can be defined as follows. When you are creating a class that does everything another class does and more, then instead of subclassing the other class, you have to declare it as a data member or property of your class.

Example Problem

Lets say you are writing a class (ClassA) that does what another class (ClassB) does. ClassA also has to do more things (have more methods) than what ClassB does. You might be tempted to simply have ClassA subclass ClassB. Resist this temptation, becuase it is the wrong thing to do. Inheritance is inherently slow, and is a very strong linkage in your design. As a rule you want to create loosely coupled, but strongly coherent systems.

Solution (design)

The correct design involves defining a data member of type ClassB in ClassA. This way, you have eliminated the need for subclassing and reduced the coupling strength. In fact, ClassB might just be an interface, which is even better for loose coupling.

Code

 1: //ClassA
 2: public class ClassA{
 3:     //data
 4:     private ClassB classB;
 5:
 6:     //methods
 7:     public void doThis(){classB.doThis();}
 8:     public void doThat(){…}
 9: }
 1: //ClassB
 2: public class ClassB{
 3:     public void doThis(){…}
 4: }

Why?

The delegation pattern allows your code to be loosely coupled, which is a very important goal of any object oriented system. It is easy to get this pattern confused with the adapter pattern, they are similar, but completely different. Study both patterns carefully and you will see how they are totally different (yet similar).



 Delegation pattern 

http://en.wikipedia.org/wiki/Delegation_pattern


In software engineering, the delegation pattern is a design pattern in object-oriented programming where an object, instead of performing one of its stated tasks, delegates that task to an associated helper object. There is an Inversion of Responsibility in which a helper object, known as a delegate, is given the responsibility to execute a task for the delegator. The delegation pattern is one of the fundamental abstraction patterns that underlie other software patterns such as composition (also referred to as aggregation), mixins and aspects.

Examples

[edit] Java examples

[edit] Simple

In this Java example, the Printer class has a print method. This print method, rather than performing the print itself, delegates to class RealPrinter. To the outside world it appears that the Printer class is doing the print, but the RealPrinter class is the one actually doing the work.
Delegation is simply passing a duty off to someone/something else. Here is a simple example:
 class RealPrinter { // the "delegate"
     void print() { 
       System.out.println("something"); 
     }
 }
 
 class Printer { // the "delegator"
     RealPrinter p = new RealPrinter(); // create the delegate 
     void print() { 
       p.print(); // delegation
     } 
 }
 
 public class Main {
     // to the outside world it looks like Printer actually prints.
     public static void main(String[] args) {
         Printer printer = new Printer();
         printer.print();
     }
 }

[edit] Complex

By using interfaces, delegation can be made more flexible and typesafe. "Flexibility" here means that C need not refer to A or B in any way, as the switching of delegation is abstracted from C. Needless to say, toA and toB don't count as references to A and B. In this example, class C can delegate to either class A or class B. Class C has methods to switch between classes A and B. Including the implements clauses improves type safety, because each class must implement the methods in the interface. The main tradeoff is more code.
interface I {
    void f();
    void g();
}
 
class A implements I {
    public void f() { System.out.println("A: doing f()"); }
    public void g() { System.out.println("A: doing g()"); }
}
 
class B implements I {
    public void f() { System.out.println("B: doing f()"); }
    public void g() { System.out.println("B: doing g()"); }
}
 
class C implements I {
    // delegation
    I i = new A();
 
    public void f() { i.f(); }
    public void g() { i.g(); }
 
    // normal attributes
    public void toA() { i = new A(); }
    public void toB() { i = new B(); }
}
 
public class Main {
    public static void main(String[] args) {
        C c = new C();
        c.f();     // output: A: doing f()
        c.g();     // output: A: doing g()
        c.toB();
        c.f();     // output: B: doing f()
        c.g();     // output: B: doing g()
    }
}

Design Pattern - Factory Pattern

From: http://developerlife.com/tutorials/?p=21

 

Problem

When using interfaces, it is important NOT to access the implementation classes (which implement these interfaces) directly.
Here is a simple example of what NOT to do:
   1: public interface LogEntryIF{
   2:      public setUserId( String s );
   3:      public setSessionId( String s );
   4:  }
   5:  
   6: public class LogEntry implements LogEntryIF{
   7:      private String userId, session;
   8:      public setUserId( String s ){ userId = s; }
   9:     public setSessionId( String s ){ sessionId = s; }
  10: }
Don’t do this:
   1: LogEntryIF le = new LogEntry();
   2: le.setUserId( “boo” );
   3: le.setSessionId( “sessionboo” );
So in this simple case, even having the ability to instantiate the LogEntry class is undesirable. There must be a way to instantiate objects of implementation classes:
  • without directly accessing the implemenation classes themselves
  • by relying entirely on the interfaces to access these objects.
Sounds impossible? Not really, by using the Factory pattern it can be done.

Solution

The Factory pattern involves creating a static class which has at least one method to do the following:
  • create an instance of an implementation classes, but return this object reference as the interface.
   1: public interface LogEntryIF{
   2:      public setUserId( String s );
   3:      public setSessionId( String s );
   4: }
   5:  
   6: public class LogEntry implements LogEntryIF{
   7:      private String userId, session;
   8:      public setUserId( String s ){ userId = s; }
   9:      public setSessionId( String s ){ sessionId = s; }
  10: }
  11:  
  12: public class LogFactory{
  13:      public static LogEntryIF getLogEntryInstance(
  14:          String userId ,
  15:          String sessionId ){
  16:          LogEntry le = new LogEntry();
  17:          le.setUserId( userId );
  18:          le.setSessionId( sessionId );
  19:          return le;
  20:      }
  21: }
Usage:
   1: LogEntryIF le = LogFactory.getLogEntryInstance( “boo” , “sessionboo” );
In the solution above, the user does not have to directly access the implementation class (LogEntry) in order to get an instance of it. Also, the factory class returns this instance of the implementation class as an instance of interface.