CSC/ECE 517 Fall 2012/ch2b 2w37 ms: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 117: Line 117:
  package com.javapapers.designpattern;
  package com.javapapers.designpattern;
   
   
  /**
 
* abstraction in bridge pattern
  // abstraction in bridge pattern
* */
 
  abstract class Vehicle {
  abstract class Vehicle {
   protected Workshop workShop1;
   protected Workshop workShop1;
Line 132: Line 132:
  }
  }
Car class  
Car class  
package com.javapapers.designpattern;
 
  //Refine abstraction 1 in bridge pattern
  /**
 
  * Refine abstraction 1 in bridge pattern
  */
  public class Car extends Vehicle {
  public class Car extends Vehicle {
   
   
Line 153: Line 151:
  }
  }
Bike Class  
Bike Class  
package com.javapapers.designpattern;
 
  // Refine abstraction 2 in bridge pattern
  /**
  * Refine abstraction 2 in bridge pattern
  */
  public class Bike extends Vehicle {
  public class Bike extends Vehicle {
   
   
Line 175: Line 170:
   
   
   // Implementor for bridge pattern
   // Implementor for bridge pattern
  public interface Workshop {
  public interface Workshop {
   abstract public void work();
   abstract public void work();
Line 183: Line 177:


  // Concrete implementation 1 for bridge pattern
  // Concrete implementation 1 for bridge pattern
  public class Produce implements Workshop {
  public class Produce implements Workshop {
   
   

Revision as of 16:35, 17 November 2012

Adapter pattern and the related patterns (Bridge, Decorator, Facade)

The adapter design pattern allows the user to make changes to the existing class with other class libraries without changing the code for the existing class. The Bridge, Decorator and the Facade pattern look somewhat similar to the adapter pattern but their intent is different and that intent is what separates the above patterns from each other.

Adapter Pattern

Adapter pattern plays an important role when you want to incompatible interfaces to work together.The real world example for an adapter pattern is the travel power adapter.Different countries have different socket and plug configuration. So you can use an adapter to fit a plug into a socket that initially was not possible due to different interface designs.

Implementattion

Adapter implementation using inheritance

This method can be used when you have incompatible method that needs to be used in other class. Using inheritance a "is-a" relationship is established between the base class and super class. The new compatible methods will be contained in the inherited adapter class.

public class CylindricalSocket {
  public String supply(String cylinStem1, String cylinStem1) {
    System.out.println("Power power power...");
  }
}

public class RectangularAdapter extends CylindricalSocket {
  public String adapt(String rectaStem1, Sting rectaStem2) {
    //some conversion logic
    String cylinStem1 = rectaStem1;
    String cylinStem2 = rectaStem2;
    return supply(cylinStem1, cylinStem2);
  }
}

public class RectangularPlug {
  private String rectaStem1;
  private String rectaStem2;
  public getPower() {
    RectangulrAdapter adapter = new RectangulrAdapter();
    String power = adapter.adapt(rectaStem1, rectaStem2);
    System.out.println(power);
  }
}
Adapter implementation using composition

The other approach is to have a base class as an attribute in the adapter class. This creates an "has-a"relationship between the base class and the sub class.

public class CylindricalSocket {
  public String supply(String cylinStem1, String cylinStem1) {
    System.out.println("Power power power...");
  }
}

public class RectangularAdapter {
  private CylindricalSocket socket;

  public String adapt(String rectaStem1, Sting rectaStem2) {
    //some conversion logic
    socket = new CylindricalSocket();
    String cylinStem1 = rectaStem1;
    String cylinStem2 = rectaStem2;
    return socket.supply(cylinStem1, cylinStem2);
  }
}

public class RectangularPlug {
  private String rectaStem1;
  private String rectaStem2;
  public getPower() {
    RectangulrAdapter adapter = new RectangulrAdapter();
    String power = adapter.adapt(rectaStem1, rectaStem2);
    System.out.println(power);
  }
}
Composition or inheritance to implement Adapter Pattern?
  • Composition is preferred over inheritance since using composition it is easy to change the behavior of a class.
Adapter pattern in Java
  • java.io.InputStreamReader(InputStream)
  • java.io.OutputStreamWriter(OutputStream)


Bridge Pattern

As stated by GoF a bridge design patterns intent is to “Decouple an abstraction from its implementation so that the two can vary independently”.

Elements of Bridge Design Pattern
  • Abstraction: This is where the abstraction interface is defined.

For example: A Vehicle class which has a manufacture method.

  • Refined Abstraction: Refined Abstraction extends the interface defined by Abstraction.

For example, a Car class or a Bike class which has a manufacture method which is more refined than the Vehicle class.

  • Implementor: It defines the interface for the implementation classes. It defines the basic operation.

For example, the Workshop class acts as an implementor with the work() method.

  • Concrete Implementation: This implements the Implementor interface and gives it a more concrete implementation.

For example the Produce and the Assemble class with the work() method provides the concrete implementation.


UML Diagram for Bridge-Pattern
Without Bridge-Pattern
With Bridge-Pattern









Example code for Bridge pattern

Vehicle Interface

package com.javapapers.designpattern;

// abstraction in bridge pattern
abstract class Vehicle {
  protected Workshop workShop1;
  protected Workshop workShop2;

  protected Vehicle(Workshop workShop1, Workshop workShop2) {
    this.workShop1 = workShop1;
    this.workShop2 = workShop2;
  }

  abstract public void manufacture();
}

Car class

//Refine abstraction 1 in bridge pattern
public class Car extends Vehicle {

  public Car(Workshop workShop1, Workshop workShop2) {
    super(workShop1, workShop2);
  }

  @Override
  public void manufacture() {
    System.out.print("Car ");
    workShop1.work();
    workShop2.work();

  }

}

Bike Class

// Refine abstraction 2 in bridge pattern
public class Bike extends Vehicle {

  public Bike(Workshop workShop1, Workshop workShop2) {
    super(workShop1, workShop2);
  }

  @Override
  public void manufacture() {
    System.out.print("Bike ");
    workShop1.work();
    workShop2.work();
  }

}

Workshop Interface

 // Implementor for bridge pattern
public interface Workshop {
  abstract public void work();
}

Produce Class

// Concrete implementation 1 for bridge pattern
public class Produce implements Workshop {

  @Override
  public void work() {
    System.out.print("Produced");
  }

}

Assemble Class

  //Concrete implementation 2 for bridge pattern
public class Assemble implements Workshop {

  @Override
  public void work() {
    System.out.println(" Assembled.");
  }

}

Demonstration of bridge design pattern

public class BridgePattern {

  public static void main(String[] args) {

    Vehicle vehicle1 = new Car(new Produce(), new Assemble());
    vehicle1.manufacture();
    Vehicle vehicle2 = new Bike(new Produce(), new Assemble());
    vehicle2.manufacture();

  }
}

Output:

Car Produced Assembled.
Bike Produced Assembled.



Bridge vs Adapter pattern
  • Two incompatable classes can be made to work together using adapter pattern.
  • Bridge pattern creates two separate hierarchies by separating the abstraction from the implementation.

Decorator Pattern

The decorator pattern adds responsibility to an object dynamically. The decorator design pattern is used to extend the behavior of an object dynamically. In order to extend the behavior we have to construct an wrapper around the object. Inheritance is not feasible since it is applied to an entire class. With the decorator pattern it is possible to select any particular instance and modify its behavior leaving the other instances unmodified.

UML Diagram for Decorator-Pattern

Implementation of Decorator Pattern

public interface Icecream {
 public String makeIcecream();
} 
public class SimpleIcecream implements Icecream {

 @Override
 public String makeIcecream() {
   return "Base Icecream";
 }

}
abstract class IcecreamDecorator implements Icecream {

 protected Icecream specialIcecream;

 public IcecreamDecorator(Icecream specialIcecream) {
   this.specialIcecream = specialIcecream;
 }

 public String makeIcecream() {
   return specialIcecream.makeIcecream();
 }
}
public class NuttyDecorator extends IcecreamDecorator {

 public NuttyDecorator(Icecream specialIcecream) {
   super(specialIcecream);
 }

 public String makeIcecream() {
   return specialIcecream.makeIcecream() + addNuts();
 }

 private String addNuts() {
   return " + cruncy nuts";
 }
}
public class HoneyDecorator extends IcecreamDecorator {

 public HoneyDecorator(Icecream specialIcecream) {
   super(specialIcecream);
 }

 public String makeIcecream() {
   return specialIcecream.makeIcecream() + addHoney();
 }

 private String addHoney() {
   return " + sweet honey";
 }
}

Adaptor Pattern vs Decorator Pattern

  • Adapter provides a different interface to its subject.
  • Decorator provides an enhanced interface.

http://sourcemaking.com/design_patterns/decorator

Facade Pattern