design pattern qa

Upload: kiran

Post on 07-Aug-2018

213 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/20/2019 Design Pattern QA

    1/171

    About Design Pattern

    What is the design pattern?

    If a problem occurs over and over again, a solution to that problem

    has been used effectively. That solution is described as a pattern.

    The design patterns are language-independent strategies for solving

    common object-oriented design problems. When you make a

    design, you should know the names of some common solutions.Learning design patterns is good for people to communicate each

    other effectively. In fact, you may have been familiar with some

    design patterns, you may not use well-known names to describe

    them. SUN suggests GOF (Gang Of Four--four pioneer guys who

    wrote a book named "Design Patterns"- Elements of Reusable

    Object-Oriented Software), so we use that book as our guide to

    describe solutions. Please make you be familiar with these termsand learn how other people solve the code problems.

    Do I have to use the design pattern?

    If you want to be a professional Java developer, you should know

    at least some popular solutions to coding problems. Such solutions

    have been proved efficient and effective by the experienced

    developers. These solutions are described as so-called design

     patterns. Learning design patterns speeds up your experience

    accumulation in OOA/OOD. Once you grasped them, you would be

     benefit from them for all your life and jump up yourselves to be a

    master of designing and developing. Furthermore, you will be able

    to use these terms to communicate with your fellows or assessors

    more effectively.

  • 8/20/2019 Design Pattern QA

    2/171

    Many programmers with many years experience don't know design

     patterns, but as an Object-Oriented programmer, you have to know

    them well, especially for new Java programmers. Actually, when

    you solved a coding problem, you have used a design pattern. Youmay not use a popular name to describe it or may not choose an

    effective way to better intellectually control over what you built.

    Learning how the experienced developers to solve the coding

     problems and trying to use them in your project are a best way to

    earn your experience and certification.

    Remember that learning the design patterns will really change how

    you design your code; not only will you be smarter but will you

    sound a lot smarter, too.

    How many design patterns?

    Many. A site says at least 250 existing patterns are used in OO

    world, including Spaghetti which refers to poor coding habits. The

    23 design patterns by GOF are well known, and more are to bediscovered on the way.

     Note that the design patterns are not idioms or algorithms or

    components.

    What is the relationship among these patterns?

    Generally, to build a system, you may need many patterns to fit

    together. Different designer may use different patterns to solve the

    same problem. Usually:

      Some patterns naturally fit together

     

    One pattern may lead to another

  • 8/20/2019 Design Pattern QA

    3/171

      Some patterns are similar and alternative

      Patterns are discoverable and documentable

      Patterns are not methods or framework

      Patterns give you hint to solve a problem effectively

    Creational Patterns 

    a. 

    Abstract Factory

    Definition

    Provides one level of interface higher than the factory pattern. It is

    used to return one of several factories.

    Where to use & benefits  Creates families of related or dependent objects like Kit.

      Provides a class library of products, exposing interface not

    implementation.

       Needs to isolate concrete classes from their super classes.

      A system needs independent of how its products are created,

    composed, and represented.  Try to enforce a constraint.

      An alternative to Facade to hide platform-specific classes

      Easily extensible to a system or a family

      Related patterns include

    o  Factory method, which is often implemented with an

    abstract factory.

  • 8/20/2019 Design Pattern QA

    4/171

    o  Singleton, which is often implemented with an abstract

    factory.

    o  Prototype, which is often implemented with an abstract

    factory.o  Facade, which is often used with an abstract factory by

     providing an interface for creating implementing class.

    Example

    Suppose you need to write a program to show data in two different

     places. Let's say from a local or a remote database. You need to

    make a connection to a database before working on the data. In this

    case, you have two choices, local or remote. You may use abstract

    factory design pattern to design the interface in the following way:

  • 8/20/2019 Design Pattern QA

    5/171

    class DataInfo {}

    interface Local {DataInfo[] loadDB(String filename);

    }

    interface Remote extends Local{void connect2WWW(String url);

    }

    class LocalMode implements Local {public DataInfo[] loadDB(String name) {

    System.out.print("Load from a local database");

    return null;}

    }

    class RemoteMode implements Remote {public void connect2WWW(String url) {

    System.out.println("Connect to a remote site");}public DataInfo[] loadDB(String name) {

    System.out.println("Load from a remotedatabase ");

    return null;}

    }

    // The Abstract Factoryinterface ConnectionFactory {Local getLocalConnection();Remote getRemoteConnection();

    }

    class DataManager implements ConnectionFactory {

  • 8/20/2019 Design Pattern QA

    6/171

      boolean local = false;DataInfo[] data;//...public Local getLocalConnection() {

    return new LocalMode();}public Remote getRemoteConnection() {

    return new RemoteMode();}public void loadData() {

    if(local){Local conn = getLocalConnection();data = conn.loadDB("db.db");

    }else {Remote conn = getRemoteConnection();

    conn.connect2WWW("www.some.where.com");data = conn.loadDB("db.db");

    }

    }// work on data

    public void setConnection(boolean b) {local = b;

    }}

  • 8/20/2019 Design Pattern QA

    7/171

     //Use the following Test class to test the aboveclassesclass Test {

    public static void main(String[] args) {DataManager dm = new DataManager();DataInfo[] di = null;String dbFileName = "db.db";if (args.length == 1) {

    //assume local is set to truedm.setConnection(true);

    LocalMode lm =(LocalMode)dm.getLocalConnection();

    di = lm.loadDB(dbFileName);} else {

    //Note: dm.local = false is defaultsetting

    RemoteMode rm =(RemoteMode)dm.getRemoteConnection();

    rm.connect2WWW("www.javacamp.org/db/");di = rm.loadDB(dbFileName);

    }//use one set of methods to deal with

    loaded data.//You don't need to worry about connection

    from this point.//Like di.find(), di.search() etc.

    }}

    C:\  Command Prompt 

    C:\> java TestConnect to a remote site

    Load from a remote database

  • 8/20/2019 Design Pattern QA

    8/171

     C:\  Command Prompt 

    C:\> java Test localLoad from a local database

    Such design is often used in SCJD project assignment. If you have

    a multiple places to load data, you just add more methods in the

    connection interface without altering other structure, or add a

    location variable in.

  • 8/20/2019 Design Pattern QA

    9/171

    b. 

    Builder

    Definition

    Construct a complex object from simple objects step by step.

    Where to use & benefits

      Make a complex object by specifying only its type and

    content. The built object is shielded from the details of itsconstruction.

      Want to decouple the process of building a complex object

    from the parts that make up the object.

      Isolate code for construction and representation.

      Give you finer control over the construction process.

      Related patterns include

    o  Abstract Factory, which focuses on the layer over the

    factory pattern (may be simple or complex), whereas a

     builder pattern focuses on building a complex object from

    other simple objects.

    o  Composite, which is often used to build a complex object.

    Example

    To build a house, we will take several steps:

    1.  build foundation,

    2.  build frame,

    3.  build exterior,

    4.  build interior.

  • 8/20/2019 Design Pattern QA

    10/171

    Let's use an abstract class HouseBuilder to define these 4 steps.

    Any subclass of HouseBuilder will follow these 4 steps to build

    house (that is to say to implement these 4 methods in the subclass).

    Then we use a WorkShop class to force the order of these 4 steps(that is to say that we have to build interior after having finished

    first three steps). The TestBuilder class is used to test the

    coordination of these classes and to check the building process.

    import java.util.*;

    class WorkShop {

    //force the order of building processpublic void construct(HouseBuilder hb) {

    hb.buildFoundation();hb.buildFrame();hb.buildExterior();hb.buildInterior();

    }}

  • 8/20/2019 Design Pattern QA

    11/171

     //set steps for building a houseabstract class HouseBuilder {

    protected House house = new House();

    protected String showProgress() {return house.toString();

    }

    abstract public void buildFoundation();abstract public void buildFrame();abstract public void buildExterior();abstract public void buildInterior();

    }

    class OneStoryHouse extends HouseBuilder {

    public OneStoryHouse(String features) {house.setType(this.getClass() + " " +

    features);}public void buildFoundation() {

    //doEngineering()//doExcavating()//doPlumbingHeatingElectricity()//doSewerWaterHookUp()//doFoundationInspection()

    house.setProgress("foundation is done");}

    public void buildFrame() {//doHeatingPlumbingRoof()//doElectricityRoute()//doDoorsWindows()//doFrameInspection()

    house.setProgress("frame is done");

  • 8/20/2019 Design Pattern QA

    12/171

      }

    public void buildExterior() {//doOverheadDoors()//doBrickWorks()//doSidingsoffitsGutters()//doDrivewayGarageFloor()//doDeckRail()//doLandScaping()house.setProgress("Exterior is done");

    }

    public void buildInterior() {//doAlarmPrewiring()//doBuiltinVacuum()//doInsulation()//doDryWall()//doPainting()//doLinoleum()//doCabinet()//doTileWork()//doLightFixtureBlinds()//doCleaning()//doInteriorInspection()house.setProgress("Interior is under

    going");}

    }

    class TwoStoryHouse extends HouseBuilder {

    public TwoStoryHouse(String features) {house.setType(this.getClass() + " " +

    features);}

    public void buildFoundation() {

  • 8/20/2019 Design Pattern QA

    13/171

      //doEngineering()//doExcavating()//doPlumbingHeatingElectricity()//doSewerWaterHookUp()//doFoundationInspection()house.setProgress("foundation is done");

    }

    public void buildFrame() {//doHeatingPlumbingRoof()//doElectricityRoute()//doDoorsWindows()//doFrameInspection()house.setProgress("frame is under

    construction");}

    public void buildExterior() {//doOverheadDoors()//doBrickWorks()//doSidingsoffitsGutters()//doDrivewayGarageFloor()//doDeckRail()//doLandScaping()house.setProgress("Exterior is waiting to

    start");}

    public void buildInterior() {//doAlarmPrewiring()//doBuiltinVacuum()//doInsulation()//doDryWall()//doPainting()//doLinoleum()

    //doCabinet()

  • 8/20/2019 Design Pattern QA

    14/171

      //doTileWork()//doLightFixtureBlinds()//doCleaning()//doInteriorInspection()house.setProgress("Interior is not started

    yet");}

    }

    class House {private String type = null;private List features = new ArrayList();

    public House() {

    }

    public House(String type) {this.type = type;

    }

  • 8/20/2019 Design Pattern QA

    15/171

     public void setType(String type) {

    this.type = type;}

    public String getType() {return type;

    }

    public void setProgress(String s) {features.add(s);

    }

    public String toString() {StringBuffer ff = new StringBuffer();String t = type.substring(6);ff.append(t + "\n ");for (int i = 0; i < features.size(); i ++)

    {ff.append(features.get(i) + "\n ");

    }return ff.toString();

    }}

    class TestBuilder {

    public static void main(String[] args) {

    HouseBuilder one = new OneStoryHouse("2bedrooms, 2.5 baths, 2-car garage, 1500 sqft");

    HouseBuilder two = new TwoStoryHouse("4bedrooms, 4 baths, 3-car garage, 5000 sqft");

    WorkShop shop = new WorkShop();

    shop.construct(one);

  • 8/20/2019 Design Pattern QA

    16/171

      shop.construct(two);

    System.out.println("Check house buildingprogress: \n");

    System.out.println(one.showProgress());System.out.println(two.showProgress());

    }}//need jdk1.5 above to compile

    C:\ Command Prompt 

    C:\> javac TestBuilder.java

    C:\> java TestBuilderCheck house building progress:

    OneStoryHouse 2 bedrooms, 2.5baths, 2-car garage, 1500 sqftfoundation is doneframe is doneExterior is doneInterior is under going

    TwoStoryHouse 4 bedrooms, 4 baths,3-car garage, 5000 sqftfoundation is doneframe is under constructionExterior is waiting to startInterior is not started yet

    C:\>

  • 8/20/2019 Design Pattern QA

    17/171

    To fine tune the above example, every do method can be designed

    as a class. Similar functional class can be designed once and used

     by other classes. e.g. Window, Door, Kitchen, etc.

    Another example, such as writing a Pizza program. Every gradient

    can be designed as a class. One pizza at least consists of several

    gradients. Different pizza has different gradients. A builder pattern

    may be adopted.

  • 8/20/2019 Design Pattern QA

    18/171

    c. 

    Factory Method 

    Definition

    Provides an abstraction or an interface and lets subclass or

    implementing classes decide which class or method should be

    instantiated or called, based on the conditions or parameters given.

    Where to use & benefits

      Connect parallel class hierarchies.

      A class wants its subclasses to specify the object.

      A class cannot anticipate its subclasses, which must be created.

      A family of objects needs to be separated by using shared

    interface.

      The code needs to deal with interface, not implemented

    classes.  Hide concrete classes from the client.

      Factory methods can be parameterized.

      The returned object may be either abstract or concrete object.

      Providing hooks for subclasses is more flexible than creating

    objects directly.

      Follow naming conventions to help other developers to

    recognize the code structure.  Related patterns include

    o  Abstract Factory , which is a layer higher than a factory

    method.

    o  Template method, which defines a skeleton of an

    algorithm to defer some steps to subclasses or avoid

    subclasses

  • 8/20/2019 Design Pattern QA

    19/171

    o  Prototype, which creates a new object by copying an

    instance, so it reduces subclasses.

    o  Singleton, which makes a returned factory method unique.

    Examples

    To illustrate such concept, let's use a simple example. To paint a

     picture, you may need several steps. A shape is an interface.

    Several implementing classes may be designed in the following

    way.

    interface Shape {public void draw();

    }

    class Line implements Shape {Point x, y;Line(Point a, Point b) {

    x = a;

    y = b;}public void draw() {

    //draw a line;}

    }

  • 8/20/2019 Design Pattern QA

    20/171

    class Square implements Shape {Point start;int width, height;Square(Point s, int w, int h) {

    start = s;width = w;height = h;

    }public void draw() {

    //draw a square;}

    }class Circle implements Shape {

    ....}

    class Painting {Point x, y;int width, height, radius;Painting(Point a, Point b, int w, int h, int r)

    {x = a;y = b;width = w;height = h;radius = r;

    }

    Shape drawLine() {return new Line(x,y);}Shape drawSquare() {

    return new Square(x, width, height);}Shape drawCircle() {

    return new Circle(x, radius);

    }

  • 8/20/2019 Design Pattern QA

    21/171

      ....}

    ...Shape pic;Painting pt;//initializing pt....if (line)

    pic = pt.drawLine();if (square)

    pic = pt.drawSquare();if (circle)

    pic = pt.drawCircle();

    From the above example, you may see that the Shape pic's type

    depends on the condition given. The variable pic may be a line or

    square or a circle.

    You may use several constructors with different parameters to

    instantiate the object you want. It is another way to design with

    Factory pattern. For example,

  • 8/20/2019 Design Pattern QA

    22/171

    class Painting {...Painting(Point a, Point b) {

    new Line(a, b); //draw a line}Painting(Point a, int w, int h) {

    new Square(a, w, h); //draw a square}Painting(Point a, int r){

    new Circle(a, r); //draw a circle}...

    }

    You may use several methods to finish the drawing jobs. It is so-

    called factory method pattern. for example,

    class Painting {...Painting(Point a, Point b) {

    draw(a, b); //draw a line}Painting(Point a, int w, int h) {

    draw(a, w, h); //draw a square}Painting(Point a, int r){

    draw(a, r); //draw a circle}

    ...}

    The above draw() methods are overloaded.

    Here is a popular example of Factory design pattern. For example,

    you have several database storages located in several places. The

  • 8/20/2019 Design Pattern QA

    23/171

     program working on the database is the same. The user may choose

    local mode or remote mode. The condition is the choice by the user.

    You may design your program with Factory pattern. When the local

    mode is set, you may instantiate an object to work on the localdatabase. If the remote mode is set, you may instantiate an object

    which may have more job to do like remote connection,

    downloading, etc.

    interface DatabaseService {public DataInfo getDataInfo() throws

    Exception;

    public FieldInfo getFieldInfo() throwsException;

    public void write(FieldInfo fi) throwsException;

    public void modify(FieldInfo fi) throwsException;

    public void delete(FieldInfo fi) throwsException;

    //...}class Data implements DatabaseService {

    public Data(String fileName) {...};public Data(URL url, String fileName) {....};public DataInfo getDataInfo() throws Exception

    {...};public FieldInfo getFieldInfo() throws

    Exception {...};public void write(FieldInfo fi) throws

    Exception {...};public void modify(FieldInfo fi) throws

    Exception {...};public void delete(FieldInfo fi) throws

    Exception {...};}class DataManager{

  • 8/20/2019 Design Pattern QA

    24/171

      Data data = null;...if (local) {

    data = new Data(localFile);...

    }if (remote){

    data = new Data(connectRemote,databaseFile);

    ...}data.write(someInfo);data.modify(someInfo);....

    }

    To illustrate how to use factory design pattern with class level

    implementation, here is a real world example. A company has a

    website to display testing result from a plain text file. Recently, thecompany purchased a new machine which produces a binary data

    file, another new machine on the way, it is possible that one will

     produce different data file. How to write a system to deal with such

    change. The website just needs data to display. Your job is to

     provide the specified data format for the website.

    Here comes a solution. Use an interface type to converge the

    different data file format. The following is a skeleton of

    implementation.

    //Let's say the interface is Displayinterface Display {

    //load a filepublic void load(String fileName);

  • 8/20/2019 Design Pattern QA

    25/171

      //parse the file and make a consistent datatype

    public void formatConsistency();

    }

    //deal with plain text fileclass CSVFile implements Display{

    public void load(String textfile) {System.out.println("load from a txt

    file");}public void formatConsistency() {

    System.out.println("txt file formatchanged");

    }}

    //deal with XML format fileclass XMLFile implements Display {

    public void load(String xmlfile) {System.out.println("load from an xml

    file");}public void formatConsistency() {

    System.out.println("xml file formatchanged");}

    }

  • 8/20/2019 Design Pattern QA

    26/171

     //deal with binary format fileclass DBFile implements Display {

    public void load(String dbfile) {System.out.println("load from a db file");

    }public void formatConsistency() {

    System.out.println("db file formatchanged");

    }}

    //Test the functionalityclass TestFactory {

    public static void main(String[] args) {Display display = null;

    //use a command line data as a triggerif (args[0].equals("1"))

    display = new CSVFile();else if (args[0].equals("2"))

    display = new XMLFile();else if (args[0].equals("3"))

    display = new DBFile();else

    System.exit(1);

    //converging code followsdisplay.load("");display.formatConsistency();

    }}//after compilation and run it

  • 8/20/2019 Design Pattern QA

    27/171

    C:\>java TestFactory 1load from a txt filetxt file format changed

    C:\>java TestFactory 2load from an xml filexml file format changed

    C:\>java TestFactory 3load from a db filedb file format changed

    In the future, the company may add more data file with different

    format, a programmer just adds a new class in accordingly. Such

    design saves a lot of code and is easy to maintain.

  • 8/20/2019 Design Pattern QA

    28/171

    d. 

    Prototype

    Definition

    Cloning an object by reducing the cost of creation.

    Where to use & benefits

      When there are many subclasses that differ only in the kind of

    objects,  A system needs independent of how its objects are created,

    composed, and represented.

      Dynamic binding or loading a method.

      Use one instance to finish job just by changing its state or

     parameters.

      Add and remove objects at runtime.

      Specify new objects by changing its structure.  Configure an application with classes dynamically.

      Related patterns include

    o  Abstract Factory, which is often used together with

     prototype. An abstract factory may store some prototypes

    for cloning and returning objects.o  Composite, which is often used with prototypes to make a

     part-whole relationship.o  Decorator , which is used to add additional functionality to

    the prototype.

    Example

  • 8/20/2019 Design Pattern QA

    29/171

    Dynamic loading is a typical object-oriented feature and prototype

    example. For example, overriding method is a kind of prototype

     pattern.

    interface Shape {public void draw();

    }

    class Line implements Shape {public void draw() {

    System.out.println("line");

    }}

    class Square implements Shape {public void draw() {

    System.out.println("square");}

    }

    class Circle implements Shape {public void draw() {

    System.out.println("circle");}

    }

  • 8/20/2019 Design Pattern QA

    30/171

    class Painting {public static void main(String[] args) {

    Shape s1 = new Line();Shape s2 = new Square();Shape s3 = new Circle();paint(s1);paint(s2);paint(s3);

    }static void paint(Shape s) {

    s.draw();}

    }----------------------------If we want to make code more readable or do morestuff, we can code the paint method in thefollowing way:

    static void paint(Shape s){if ( s instanceof Line)

    s.draw();//more job here

    if (s instanceof Square)s.draw();//more job here

    if (s instanceof Circle)s.draw();

    //more job here}nd Prompt 

    C:\> java Paintinglinesquarecircle

  • 8/20/2019 Design Pattern QA

    31/171

    The paint method takes a variable of Shape type at runtime. The

    draw method is called based on the runtime type.

    Overloading method is a kind of prototype too.

    class Painting {public void draw(Point p, Point p2) {

    //draw a line}public void draw(Point p, int x, int y) {

    //draw a square}

    public void draw(Point p, int x) {//draw a circle

    }}

    The draw method is called to draw the related shape based on the

     parameters it takes.

    The prototype is typically used to clone an object, i.e. to make acopy of an object. When an object is complicated or time

    consuming to be created , you may take prototype pattern to make

    such object cloneable. Assume the Complex class is a complicated,

    you need to implement Cloneable interface and override the clone

    method(protected Object clone()).

    class Complex implements Cloneable {int[] nums = {1,2,3,4,5};public Object clone() {

    try {return super.clone();

    }catch(CloneNotSupportedException cnse) {System.out.println(cnse.getMessage());return null;

    }

  • 8/20/2019 Design Pattern QA

    32/171

      }int[] getNums() {

    return nums;}

    }class Test {

    static Complex c1 = new Complex();static Complex makeCopy() {

    return (Complex)c1.clone();}public static void main(String[] args) {

    Complex c1 = makeCopy();int[] mycopy = c1.getNums();for(int i = 0; i < mycopy.length; i++)

    System.out.print(mycopy[i]);}

    }

    C:\ Command Prompt 

    C:\> java Test12345

    Cloning is a shallow copy of the original object. If the cloned

    object is changed, the original object will be changed accordingly.

    See the following alteration.

    class Complex implements Cloneable {int[] nums = {1,2,3,4,5};public Object clone() {

    try {return super.clone();

    }catch(CloneNotSupportedException cnse) {System.out.println(cnse.getMessage());

    return null;

  • 8/20/2019 Design Pattern QA

    33/171

      }}int[] getNums() {

    return nums;}

    }class Test {

    Complex c1 = new Complex();Complex makeCopy() {

    return (Complex)c1.clone();}public static void main(String[] args) {

    Test tp = new Test();Complex c2 = tp.makeCopy();int[] mycopy = c2.getNums();mycopy[0] = 5; System.out.println();System.out.print("local array: ");for(int i = 0; i < mycopy.length; i++)

    System.out.print(mycopy[i]);System.out.println();

    System.out.print("cloned object: ");for(int ii = 0; ii < c2.nums.length; ii++)

    System.out.print(c2.nums[ii]);System.out.println();

    System.out.print("original object: ");for(int iii = 0; iii < tp.c1.nums.length;iii++)

    System.out.print(tp.c1.nums[iii]);}

  • 8/20/2019 Design Pattern QA

    34/171

     C:\> java Test

    local array: 52345cloned object: 52345original object: 52345

    To avoid such side effect, you may use a deep copy instead of a

    shallow copy. The following shows the alteration to the above

    example, note that the Complex class doesn't implement Cloneable

    interface.

    class Complex { int[] nums = {1,2,3,4,5};public Complex clone() {

    return new Complex();} int[] getNums() {

    return nums;

    }}class Test2 {

    Complex c1 = new Complex();Complex makeCopy() {

    return (Complex)c1.clone();}public static void main(String[] args) {

    Test2 tp = new Test2();Complex c2 = tp.makeCopy();int[] mycopy = c2.getNums();mycopy[0] = 5;

    System.out.println();System.out.print("local array: ");for(int i = 0; i < mycopy.length; i++)

    System.out.print(mycopy[i]);

  • 8/20/2019 Design Pattern QA

    35/171

      System.out.println();

    System.out.print("cloned object: ");for(int ii = 0; ii < c2.nums.length; ii++)

    System.out.print(c2.nums[ii]);System.out.println();

    System.out.print("original object: ");for(int iii = 0; iii < tp.c1.nums.length;

    iii++)System.out.print(tp.c1.nums[iii]);

    }}

    C:\> java Test2

    local array: 52345cloned object: 52345original object: 12345 

    e. 

    Singleton 

    Definition

    One instance of a class or one value accessible globally in anapplication.

    Where to use & benefits

      Ensure unique instance by defining class final to prevent

    cloning.

      May be extensible by the subclass by defining subclass final.

  • 8/20/2019 Design Pattern QA

    36/171

      Make a method or a variable public or/and static.

      Access to the instance by the way you provided.

      Well control the instantiation of a class.

      Define one value shared by all instances by making it static.  Related patterns include

    o  Abstract factory, which is often used to return unique

    objects.o

      Builder , which is used to construct a complex object,

    whereas a singleton is used to create a globally accessible

    object.

    o  Prototype, which is used to copy an object, or create an

    object from its prototype, whereas a singleton is used to

    ensure that only one prototype is guaranteed.

    Example

    One file system, one window manager, one printer spooler, one

    Test engine, one Input/Output socket and etc.

    To design a Singleton class, you may need to make the class final

    like java.Math, which is not allowed to subclass, or make a variable

    or method public and/or static, or make all constructors private to

     prevent the compiler from creating a default one.

    For example, to make a unique remote connection,

    final class RemoteConnection {private Connect con;private static RemoteConnection rc = new

    RemoteConnection(connection);private RemoteConnection(Connect c) {

    con = c;....

    }

  • 8/20/2019 Design Pattern QA

    37/171

      public static RemoteConnectiongetRemoteConnection() {

    return rc;}public void setConnection(Connect c) {

    this(c);}

    }

    usage:RemoteConnection rconn =RemoteConnection.getRemoteConnection;rconn.loadData();...

    The following statement may fail because of theprivate constructorRemoteConnection con = newRemoteConnection(connection); //failed

    //failed because you cannot subclass it (finalclass)class Connection extends RemoteConnection {}

    For example, to use a static variable to control the instance;

    class Connection {

    public static boolean haveOne = false;public Connection() throws Exception{

    if (!haveOne) {doSomething();haveOne = true;

    }else {throw new Exception("You cannot have a

    second instance");

    }

  • 8/20/2019 Design Pattern QA

    38/171

      }public static Connection getConnection()

    throws Exception{return new Connection();

    }void doSomething() {}//...public static void main(String [] args) {

    try {Connection con = new Connection();

    //ok}catch(Exception e) {

    System.out.println("first: "+e.getMessage());

    }try {

    Connection con2 =Connection.getConnection(); //failed.

    }catch(Exception e) {System.out.println("second: "

    +e.getMessage());}

    }}

    C:\ Command Prompt 

    C:\> java Connectionsecond: You cannot have a secondinstance

    For example to use a public static variable to ensure a unique.

    class Employee {public static final int companyID = 12345;public String address;

  • 8/20/2019 Design Pattern QA

    39/171

      //...

    }class HourlyEmployee extends Employee {

    public double hourlyRate;//....

    }class SalaryEmployee extends Employee {

    public double salary;//...

    }class Test {

    public static void main(String[] args) {Employee Evens = new Employee();HourlyEmployee Hellen = new

    HourlyEmployee();SalaryEmployee Sara = new SalaryEmployee();System.out.println(Evens.companyID ==

    Hellen.companyID); //trueSystem.out.println(Evens.companyID ==

    Sara.companyID); //true}

    }

    C:\ Command Prompt 

    C:\> java Testtruetrue

    The companyID is a unique and cannot be altered by

    all subclasses.

  • 8/20/2019 Design Pattern QA

    40/171

     

    Note that Singletons are only guaranteed to beunique within a given class

    loader. If you use the same class across multipledistinct enterprise

    containers, you'll get one instance for eachcontainer.

    Whether you need to use synchronized keyword tomanage the method access, it depends on yourproject situation and thread controlling.

  • 8/20/2019 Design Pattern QA

    41/171

    Structural Patterns 

    a. Adapter

    Definition

    Convert the existing interfaces to a new interface to achieve

    compatibility and reusability of the unrelated classes in one

    application. Also known as Wrapper pattern.

    Where to use & benefits

      Try to match an interface(WindowAdapter, etc.)

      Make unrelated classes work together.

      Multiple compatibility.

      Increase transparency of classes.

      Make a pluggable kit.  Delegate objects.

      Highly class reusable.

      Achieve the goal by inheritance or by composition

      Related patterns include

    o  Proxy, which provides the same interface as its subject,

    whereas an adapter provides a different interface to the

    object it adapts.o  Decorator , which focuses on adding new functions to an

    object, whereas an adapter coordinates two different

    objects.

    o  Bridge, which tries to separate an interface from its

    implementation and make an object vary independently,

    whereas an adapter tries to change and cooperate the

    interface of an object.

  • 8/20/2019 Design Pattern QA

    42/171

    Example

    The famous adapter classes in Java API are

    WindowAdapter,ComponentAdapter, ContainerAdapter,FocusAdapter, KeyAdapter, MouseAdapter and

    MouseMotionAdapter.

    As you know, WindowListner interface has seven methods.

    Whenever your class implements such interface, you have to

    implements all of the seven methods. WindowAdapter class

    implements WindowListener interface and make seven empty

    implementation. When you class subclass WindowAdapter class,

    you may choose the method you want without restrictions. The

    following give such an example.

    public interface Windowlistener {public void windowClosed(WindowEvent e);public void windowOpened(WindowEvent e);

    public void windowIconified(WindowEvent e);public void windowDeiconified(WindowEvent e);public void windowActivated(WindowEvent e);public void windowDeactivated(WindowEvent e);public void windowClosing(WindowEvent e);

    }

  • 8/20/2019 Design Pattern QA

    43/171

    public class WindowAdapter implementsWindowListner{

    public void windowClosed(WindowEvent e){}public void windowOpened(WindowEvent e){}public void windowIconified(WindowEvent e){}public void windowDeiconified(WindowEvent e){}public void windowActivated(WindowEvent e){}public void windowDeactivated(WindowEvent e){}public void windowClosing(WindowEvent e){}

    }

    Here is a test program

    import javax.swing.*;import java.awt.event.*;class Test extends JFrame {

    public Test () {setSize(200,200);setVisible(true);

    addWindowListener(new Closer());}public static void main(String[] args) {

    new Test();}class Closer extends WindowAdapter {

    public void windowClosing(WindowEvent e) {System.exit(0);

    }}

    }

    To reuse classes and make new class compatible with existing ones.

    For example, A clean system is already designed, you want to add

    more job in, the Extra interface uses adapter pattern to plug in the

    existing system.

  • 8/20/2019 Design Pattern QA

    44/171

    interface Clean {public void makeClean();

    }class Office implements Clean{

    public void makeClean() {System.out.println("Clean Office");

    }}class Workshop implements Clean{

    public void makeClean() {System.out.println("Clean Workshop");

    }}

    interface Extra extends Clean{public void takeCare();

    }class Facility implements Extra{

    public void makeClean() {System.out.println("Clean Facility");

    }public void takeCare() {

    System.out.println("Care has been taken");}

    }In order to reuse Workshop and Office classes,wecreate an adapter interface Extra and

    add new job takeCare in the system.

    class Test {static void Jobs (Extra job) {

    if (job instanceof Clean)((Clean)job).makeClean();

    if (job instanceof Extra)((Extra)job).takeCare();

    }

  • 8/20/2019 Design Pattern QA

    45/171

      public static void main(String[] args) {Extra e = new Facility();Jobs(e);Clean c1 = new Office();Clean c2 = new Workshop();c1.makeClean();c2.makeClean();e.makeClean();

    }

    } C:\ Command Prompt 

    C:\> java TestClean FacilityCare has been takenClean OfficeClean WorkshopClean Facility

    By composition, we can achieve adapter pattern. It is also called

    wrapper. For example, a Data class has already been designed andwell tested. You want to adapt such class to your system. You may

    declare it as a variable and wrapper or embed it into your class.

    //well-tested classclass Data {

    public void add(Info){}public void delete(Info) {}

    public void modify(Info){}//...

    }

    //Use Data class in your own classclass AdaptData {

    Data data;public void add(Info i) {

    data.add(i);

  • 8/20/2019 Design Pattern QA

    46/171

      //more job}public void delete(Info i) {

    data.delete(i);//more job

    }public void modify(Info i) {

    data.modify(i);//more job

    }//more stuff here//...

    }

  • 8/20/2019 Design Pattern QA

    47/171

    b. Bridge 

    Definition

    Decouple an abstraction or interface from its implementation so

    that the two can vary independently.

    Where to use & benefits

      Want to separate abstraction and implementation permanently

      Share an implementation among multiple objects

      Want to improve extensibility

      Hide implementation details from clients

      Related patterns include

    o  Abstract Factory, which can be used to create and

    configure a particular bridge.o  Adapter , which makes unrelated classes work together,

    whereas a bridge makes a clear-cut between abstraction

    and implementation.

    Examples

    If you have a question database, you may want to develop a

     program to display it based on the user selection. The following is asimple example to show how to use a Bridge pattern to decouple

    the relationship among the objects.

    import java.util.*;

    //abstractioninterface Question {

  • 8/20/2019 Design Pattern QA

    48/171

      public void nextQuestion();public void priorQuestion();public void newQuestion(String q);public void deleteQuestion(String q);public void displayQuestion();public void displayAllQuestions();

    }

    //implementationclass QuestionManager {

    protected Question questDB; //instantiate itlaterpublic String catalog;

    public QuestionManager(String catalog) {this.catalog = catalog;

    }

    public void next() {questDB.nextQuestion();

    }

  • 8/20/2019 Design Pattern QA

    49/171

      public void prior() {questDB.priorQuestion();

    }

    public void newOne(String quest) {questDB.newQuestion(quest);

    }

    public void delete(String quest) {questDB.deleteQuestion(quest);

    }

    public void display() {questDB.displayQuestion();

    }

    public void displayAll() {System.out.println("Question Catalog: " +

    catalog);questDB.displayAllQuestions();

    }}

    //further implementationclass QuestionFormat extends QuestionManager {

    public QuestionFormat(String catalog){super(catalog);}

    public void displayAll() {

    System.out.println("\n~~~~~~~~~~~~~~~~~~~~~~~~");

    super.displayAll();

  • 8/20/2019 Design Pattern QA

    50/171

     System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~");

    }}

    //decoupled implementationclass JavaQuestions implements Question {

    private List questions = newArrayList();

    private int current = 0;

    public JavaQuestions() {//load from a database and fill in the

    containerquestions.add("What is Java? ");questions.add("What is an interface? ");questions.add("What is cross-platform? ");questions.add("What is UFT-8? ");questions.add("What is abstract? ");questions.add("What is Thread? ");questions.add("What is multi-threading?

    ");

    }

    public void nextQuestion() {

    if( current 0 )

    current--;

    }

  • 8/20/2019 Design Pattern QA

    51/171

     public void newQuestion(String quest) {

    questions.add(quest);}

    public void deleteQuestion(String quest) {questions.remove(quest);

    }

    public void displayQuestion() {System.out.println( questions.get(current)

    );}

    public void displayAllQuestions() {for (String quest : questions) {

    System.out.println(quest);}

    }}

    class TestBridge {public static void main(String[] args) {

    QuestionFormat questions = newQuestionFormat("Java Language");

    questions.questDB = newJavaQuestions();//can be hooked up with otherquestion class

    //questions.questDB = newCsharpQuestions();

    //questions.questDB = newCplusplusQuestions();

    questions.display();

  • 8/20/2019 Design Pattern QA

    52/171

      questions.next();

    questions.newOne("What is object? ");questions.newOne("What is reference

    type?");

    questions.displayAll();}

    }//need jdk1.5 to compile

    C:\ Command Prom 

    C:\> javac TestBridge.javaC:\> java TestBridgeWhat is Java?

    ~~~~~~~~~~~~~~~~~~~~~~~~Question Catalog: Java LanguageWhat is Java?What is an interface?What is cross-platform?What is UFT-8?What is abstract?What is Thread?What is multi-threading?What is object?What is reference type?~~~~~~~~~~~~~~~~~~~~~~~~

    C:\>

     Note that the JavaQuestion class can be launched independently

    and work as its own system. Here we just show you how to use

    Bridge pattern to decouple the interface from its implementation.

  • 8/20/2019 Design Pattern QA

    53/171

     

    c. 

    Composite

    Definition

    Build a complex object out of elemental objects and itself like a

    tree structure.

    Where to use & benefits  Want to represent a part-whole relationship like tree folder

    system

      Group components to form larger components, which in turn

    can be grouped to form still larger components.

      Related patterns include

    o  Decorator , which is often used with composite pattern and

    with the same parent class.

    o  Flyweight, which is used with composite pattern to share

    components.o  Iterator , which is used to traverse the composites.

    o  Visitor , which localizes operations across composite and

    leaf classes.

    Example

    A component has many elements and itself which has many

    elements and itself, etc. A file system is a typical example.

    Directory is a composite pattern. When you deal with Directory

    object, if isFile() returns true, work on file, if isDirectory() returns

    true, work on Directory object.

  • 8/20/2019 Design Pattern QA

    54/171

    class Directory {Directory dir;File[] f;...

    boolean isDirectory() {return f == null;

    }boolean isFile() {

    return f != null;}File getFile(int i) {

    if (isFile())return f[i];

    return null'}Directory getDirectory() {

    if (isDirectory())return dir;

    return null;}....

    }

    For example, General Manager may have several employees and

    some of employees are Managers which have several employees.

    To illustrate such issue, we design a simple Manager class.

    class Employee {String name;double salary;Employee(String n, double s){

    name = n;salary = s;

    }String getName() {

    return name;

  • 8/20/2019 Design Pattern QA

    55/171

      }double getSalary() {

    return salary;}public String toString() {

    return "Employee " + name;}

    }class Manager {

    Manager mgr;Employee[] ely;String dept;Manager(Manager mgr,Employee[] e, String d ) {

    this(e, d);this.mgr = mgr;

    }

    Manager(Employee[] e, String d) {ely = e;dept =d;

    }String getDept() {

    return dept;}

  • 8/20/2019 Design Pattern QA

    56/171

      Manager getManager() {return mgr;

    }Employee[] getEmployee() {

    return ely;}public String toString() {

    return dept + " manager";}

    }

    class Test {public static void main(String[] args) {

    Employee[] e1 = {new Employee("Aaron", 50),new Employee("Betty",

    60)};Manager m1 = new Manager(e1, "Accounting");

    Employee[] e2 = {new Employee("Cathy", 70),new Employee("Dan", 80),new Employee("Eliz", 90)};

    Manager m2 = new Manager(m1, e2,"Production");

    System.out.println(m2);Employee[] emp = m2.getEmployee();if (emp != null)

    for (int k = 0; k < emp.length; k++)System.out.println(" "+emp[k]+"Salary: $"+ emp[k].getSalary());

    Manager m = m2.getManager();System.out.println(" " + m);if (m!= null) {

    Employee[] emps = m.getEmployee();if (emps != null)

    for (int k = 0; k < emps.length; k++)

  • 8/20/2019 Design Pattern QA

    57/171

      System.out.println(" " +emps[k]+" Salary: $"+ emps[k].getSalary());

    }}

    }

    C:\ Command Prompt 

    C:\> java TestProduction manager

    Employee Cathy Salary: $70.0Employee Dan Salary: $80.0Employee Eliz Salary: $90.0Accounting managerEmployee Aaron Salary: $50.0Employee Betty Salary: $60.0

  • 8/20/2019 Design Pattern QA

    58/171

    d. 

    Decorator 

    Definition

    Attach additional responsibilities or functions to an object

    dynamically or statically. Also known as Wrapper.

    Where to use & benefits

      Provide an alternative to subclassing.  Add new function to an object without affecting other objects.

      Make a responsibility easily added and removed dynamically.

      More flexibility than static inheritance.

      Transparent to the object.

      Related patterns include

    o  Adapter pattern, which provides a different interface to

    the object it adapts, whereas a decorator changes anobject's responsibilities,

    o  Proxy pattern, which controls access to the object,

    whereas a decorator focuses on adding new functions to

    an object,

    o  Composite pattern, which aggregates an object, whereas a

    decorator adds additional responsibilities to an object, and

    o  Strategy pattern, which changes the guts of an object,

    whereas a decorator changes the skin of an object.

    o  Facade pattern, which provides a way of hiding a complex

    class, whereas a decorator adds function by wrapping a

    class.

    Example

  • 8/20/2019 Design Pattern QA

    59/171

    A JScrollPane object can be used to decorate a JTextArea object or

    a JEditorPane object. A window can be decorated with different

     borders like BevelBorder, CompoundBorder, EtchedBorder

    TitledBorder etc. These border classes working as decorators are provided in Java API.

    Decorator pattern can be used in a non-visual fashion. For example,

    BufferedInputStream, DataInputStream, and CheckedInputStream

    are decorating objects of FilterInputStream class. These decorators

    are standard Java API classes.

    To illustrate a simple decorator pattern in non-visual manner, wedesign a class that prints a number. We create a decorator class that

    adds a text to the Number object to indicate that such number is a

    random number. Of course we can subclass the Number class to

    achieve the same goal. But the decorator pattern provides us an

    alternative way.

    import java.util.Random;class Number {public void print() {

    System.out.println(new Random().nextInt());}

    }

    class Decorator {

    public Decorator() {System.out.print("Random number: ");//add

    a description to the number printednew Number().print();

    }}

    class SubNumber extends Number{

    public SubNumber() {

  • 8/20/2019 Design Pattern QA

    60/171

      super();System.out.print("Random number: ");print();

    }}

    class Test {public static void main(String[] args) {

    new Decorator();new SubNumber();

    }}java TestRandom number: 145265744Random number: 145265755

    e. 

    Façade

    Definition

    Make a complex system simpler by providing a unified or general

    interface, which is a higher layer to these subsystems.

    Where to use & benefits

      Want to reduce complexities of a system.

      Decouple subsystems , reduce its dependency, and improve

     portability.

      Make an entry point to your subsystems.

  • 8/20/2019 Design Pattern QA

    61/171

      Minimize the communication and dependency between

    subsystems.

      Security and performance consideration.

      Shield clients from subsystem components.  Simplify generosity to specification.

      Related patterns include

    o  Abstract Factory, which is often used to create an

    interface for a subsystem in an independent way, and can

     be used as an alternative way to a facade.o  Singleton, which is often used with a facade.

    o  Mediator , which is similar to facade, but a facade doesn't

    define new functionality to the subsystem.

    Example

    JDBC design is a good example of Façade pattern. A database

    design is complicated. JDBC is used to connect the database and

    manipulate data without exposing details to the clients.

    Security of a system may be designed with Façade pattern. Clients'

    authorization to access information may be classified. General

    users may be allowed to access general information; special guests

    may be allowed to access more information; administrators and

    executives may be allowed to access the most important

    information. These subsystems may be generalized by one

    interface. The identified users may be directed to the relatedsubsystems.

    interface General {public void accessGeneral();

    }interface Special extends General {

    public void accessSpecial();

    }

  • 8/20/2019 Design Pattern QA

    62/171

    interface Private extends General {public void accessPrivate();

    }

    class GeneralInfo implements General {public void accessGeneral() {//...}//...

    }class SpecialInfo implements Special{

    public void accessSpecial() {//...

    }public void accessGeneral() {}//...

    }class PrivateInfo implements Private, Special {

    public void accessPrivate() {// ...}public void accessSpecial() {//...}public void accessGeneral() {// ...}

    //...}

    class Connection {//...

    if (user is unauthorized) throw newException();

    if (user is general) return new GeneralInfo();

  • 8/20/2019 Design Pattern QA

    63/171

      if (user is special) return new SpecialInfo();if (user is executive) return new

    PrivateInfo();//...

    }

    The above code example illustrates that the whole system is not

    exposed to the clients. It depends on the user classification.

    Mr. SudHakar Chavali proposes a better design, similar to the

    above, but avoids repeated code. Look at code below.interface General {

    public void accessGeneral();}

    interface Special extends General {

    public void accessSpecial();

    }

    interface Private extends General {

    public void accessPrivate();

    }

    class GeneralInfo implements General {

    public void accessGeneral() {

    //...}

    //...

    }

  • 8/20/2019 Design Pattern QA

    64/171

     class SpecialInfo extends GeneralInfo implementsSpecial{

    public void accessSpecial() {

    //...}

    }

    class PrivateInfo extends SpecialInfo implementsPrivate {

    public void accessPrivate() {

    // ...

    }

    //...}

    To avoid repeated code, SpecialInfo become subclass of

    GeneralInfo and PrivateInfo becomes subclass of SpecialInfo.

    When a person is exposed to special information, that person is

    allowed to access general information also. When a person is

    exposed to private information, that person is allowed to accessgeneral information and special information also.

    When you design a mortgage process system, you may consider the

     process of checking client's bank, credit and other loan information.

    Facade design may be a choice.

  • 8/20/2019 Design Pattern QA

    65/171

    f. 

    Flyweight 

    Definition

    Make instances of classes on the fly to improve performance

    efficiently, like individual characters or icons on the screen.

    Where to use & benefits

       Need to instantiate a large amount of small and fine-grained

    classes.

       Need icons to represent object.

      An object extrinsic state can be shared by classes.

      Reduce the number of objects created, decrease memory

    footprint and increase performance.

      Increase runtime cost associated with transferring, finding, or

    computing extrinsic data.  Related patterns include

    o  Composite, which supports recursive structures, whereas

    an flyweight is often applied on it.

    o  Factory Method, which produces specific object upon

    requirement, whereas an flyweight uses it to reduce

    objects.

    o  State, which allows an object to alter its behavior when its

    internal state is changed, whereas a flyweight is best

    implemented on it.

    o  Strategy, which allows an algorithm vary independently to

    suit its needs, whereas a flyweight is based on such

    strategy.

    Examples

  • 8/20/2019 Design Pattern QA

    66/171

    In order to share an object, we may declare an interface and an

    intrinsic state through which flyweights can receive and act on it. If

    you want to show a file system with folders to show the directories

    or subdirectories, you don't need to load all the files or directoriesat one loading time. You may show the upper level folders first. If

    the user clicks a folder, then load its subdirectories and files. The

    shared trigger is mouse-clicked. The composite pattern may be

    combined to define the flyweight system.

    class Folder {void draw(..) {}

    }class FolderFactory {

    ...if (selected) {

    return aFolder;else

    return aFile;...

    }

    ...

    To show how to use flyweight to reduce object creation, we will

    make a program to draw 1000 circles with 6 different colors.

    Before we customize it to a flyweight design, it is coded as follows:

  • 8/20/2019 Design Pattern QA

    67/171

    import java.awt.*;import java.awt.Color;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;

    class Test extends JFrame{private static final Color colors[] = {

    Color.red, Color.blue,

    Color.yellow, Color.orange,

    Color.black, Color.white };private static final int WIDTH_ = 400,

    HEIGHT = 400,NUMBER_OF_CIRCLES =

    1000;

    public Test() {Container contentPane = getContentPane();

    JButton button = new JButton("Draw Circle");final JPanel panel = new JPanel();

    contentPane.add(panel,BorderLayout.CENTER);

    contentPane.add(button, BorderLayout.SOUTH);

    setSize(WIDTH,HEIGHT);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setVisible(true);

    button.addActionListener(newActionListener() {

    public void actionPerformed(ActionEvent

    event) {

  • 8/20/2019 Design Pattern QA

    68/171

      Graphics g = panel.getGraphics();

    for(int i=0; i < NUMBER_OF_CIRCLES;++i) {

    g.setColor(getRandomColor());int r = getRandomR();g.drawOval(getRandomX(),

    getRandomY(), r, r); }

    }});

    }

    private int getRandomX() {return (int)(Math.random()*WIDTH );

    }private int getRandomY() {

    return (int)(Math.random()*HEIGHT);}private int getRandomR() {

    return (int)(Math.random()*(HEIGHT/10));}private Color getRandomColor() {

    returncolors[(int)(Math.random()*colors.length)];

    }public static void main(String[] args) {

    Test test = new Test();}}

    Copy, paste above code, and run it to see the functionality. and

    Prompt 

    C:\> java Test

  • 8/20/2019 Design Pattern QA

    69/171

     Note that the above program doesn't take advantage of reusability

    of OOP. We will customize it and make a Circle object, so the

    Circle object can be reused.

    class Circle {private Color color;

    public Circle(Color color) {this.color = color;

    }public void draw(Graphics g, int x, int y, int

    r) { g.setColor(color);g.drawOval(x, y, r, r);

    }}

    Then we rewrite the program. It is possible for people to rewrite

    with Circle object in the following way:

    import java.awt.*;import java.awt.Color;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;

    class Test extends JFrame{private static final Color colors[] = {

    Color.red, Color.blue,

    Color.yellow, Color.orange,

    Color.black, Color.white };private static final int WIDTH = 400,

    HEIGHT = 400,NUMBER_OF_CIRCLES =

    1000;

  • 8/20/2019 Design Pattern QA

    70/171

     public Test() {

    Container contentPane = getContentPane();

    JButton button = new JButton("Draw Circle");final JPanel panel = new JPanel();

    contentPane.add(panel,BorderLayout.CENTER);

    contentPane.add(button, BorderLayout.SOUTH);setSize(WIDTH ,HEIGHT);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setVisible(true);

    button.addActionListener(newActionListener() {

    public void actionPerformed(ActionEventevent) {

    Graphics g = panel.getGraphics();

    for(int i=0; i < NUMBER_OF_CIRCLES; ++i){

    Circle circle = newCircle(getRandomColor());

    circle.draw(g, getRandomX(), getRandomY(),getRandomR());//1000 object created.

    }}

    });}

    private int getRandomX() {return (int)(Math.random()*WIDTH );

    }

    private int getRandomY() {return (int)(Math.random()*HEIGHT);

  • 8/20/2019 Design Pattern QA

    71/171

      }private int getRandomR() {

    return (int)(Math.random()*(HEIGHT/10));}private Color getRandomColor() {

    returncolors[(int)(Math.random()*colors.length)];

    }public static void main(String[] args) {

    Test test = new Test();}

    }

    From the above code, you may note that 1000 circle object has

     been created. It is memory consuming.

    To improve it, we will create a CircleFactory class to customize it

     by using flyweight design pattern. Since we just draw circle with

    different colors, we can store color info in a hashmap. If a circle

    has been drawn, the new circle will be checked with color. If thecircle with the same color has been found in the hashmap, the circle

    will share the instance which is picked up from the hashmap

    instead of creating a new one. We will reuse the object with

    different state, that is to say we will share the instance and draw the

    circle with different start position and radius on the fly.

    class CircleFactory {

    //store colorprivate static final HashMap circleByColor =

    new HashMap();

    public static Circle getCircle(Color color) {Circle circle =

    (Circle)circleByColor.get(color);

    if(circle == null) {

  • 8/20/2019 Design Pattern QA

    72/171

      circle = new Circle(color);circleByColor.put(color, circle);System.out.println("Creating " + color +

    " circle");//see how many objects we create oncommand line

    }return circle;

    }}

    So our test program will be coded as follows:

    import java.awt.*;import java.util.HashMap;import java.awt.Color;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;

    class Test extends JFrame{

    private static final Color colors[] = {Color.red, Color.blue,

    Color.yellow, Color.orange,

    Color.black, Color.white };private static final int WIDTH = 400,

    HEIGHT = 400,

    NUMBER_OF_CIRCLES =1000;

    public Test() {Container contentPane = getContentPane();

    JButton button = new JButton("Draw Circle");final JPanel panel = new JPanel();

  • 8/20/2019 Design Pattern QA

    73/171

      contentPane.add(panel,BorderLayout.CENTER);

    contentPane.add(button, BorderLayout.SOUTH);setSize(WIDTH,HEIGHT);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setVisible(true);

    button.addActionListener(newActionListener() {

    public void actionPerformed(ActionEventevent) {

    Graphics g = panel.getGraphics();for(int i=0; i < NUMBER_OF_CIRCLES;

    ++i) {Circle circle =

    CircleFactory.getCircle(getRandomColor());circle.draw(g, getRandomX(),

    getRandomY(),getRandomR()); //Since we have 6 different colors,

    we have 6 objects created.}

    }});

    }public static void main(String[] args) {

    Test test = new Test();

    }private int getRandomX() {return (int)(Math.random()*WIDTH );

    }private int getRandomY() {

    return (int)(Math.random()*HEIGHT);}private int getRandomR() {

    return (int)(Math.random()*(HEIGHT/10));

  • 8/20/2019 Design Pattern QA

    74/171

      }private Color getRandomColor() {

    returncolors[(int)(Math.random()*colors.length)];

    }}

    class CircleFactory {private static final HashMap circleByColor =

    new HashMap();

    public static Circle getCircle(Color color) {Circle circle =

    (Circle)circleByColor.get(color);

    if(circle == null) {circle = new Circle(color);circleByColor.put(color, circle);System.out.println("Creating " + color +

    " circle");}return circle;

    }}

    class Circle {private Color color;

    public Circle(Color color) {this.color = color;

    }public void draw(Graphics g, int x, int y, int

    r) {g.setColor(color);g.drawOval(x, y, r, r);

    }

  • 8/20/2019 Design Pattern QA

    75/171

    }

    Copy, paste above code and run it. You will see the printout from

    the command line, that you only have 6 objects created, not 1000

    objects because you only have 6 colors. Such a big reduction of

    object creation will improve your program performance

    dramatically.

    C:\ Command Prompt 

    C:\> java TestCreatingjava.awt.Color[r=255,g=0,b=0]circleCreatingjava.awt.Color[r=0,g=0,b=0] circleCreatingjava.awt.Color[r=255,g=200,b=0]

    circleCreatingjava.awt.Color[r=255,g=255,b=0]circleCreatingjava.awt.Color[r=0,g=0,b=255]circleCreating

    java.awt.Color[r=255,g=255,b=255]circle

    Flyweight design is effective with instantiating a large amount of

    small and fine-grained classes by combining with factory design

     pattern.

  • 8/20/2019 Design Pattern QA

    76/171

    If you have jdk1.5 installed, you may need to use a tool to check if

    you save the memory by running your commands as follows:

    C:\ Command Prompt 

    C:\> java -Dcom.sun.management.jmxremote Test

    And open another console as follows:

    C:\ Command Prompt 

    C:\> jconsole

    The jconsole tool will hook up your program Test to give your

    statistic numbers about your program, such as threads, heap,

    memory, VM, etc.

    String class is designed with Flyweight design pattern. It has

    similar structure as above example. When you create a string

    constant, such constant is stored in a pool. When the second string

    is created, it will be checked to see if it has been created. If it is

    true, the second string instance will be picked up from the string

     pool instead of creating a new one. This is why the following code

    makes sense, but bothers many people.String s1 = "hello";String s2 = "hello"; //store in a string pool.String s3 = new String("hello");

    System.out.println(s1==s2); //true, share the samememmory addressSystem.out.println(s1==s3); //false

  • 8/20/2019 Design Pattern QA

    77/171

    g. 

    Proxy

    Definition

    Use a simple object to represent a complex one or provide a

     placeholder for another object to control access to it.

    Where to use & benefits

      If creating an object is too expensive in time or memory.  Postpone the creation until you need the actual object.

      Load a large image (time consuming).

      Load a remote object over network during peak periods.

      Access right is required to a complex system.

      Related patterns include

    o  Adapter pattern, which provides a different interface to

    the object it adapts, whereas a proxy provides the sameinterface as its subject, and

    o  Decorator pattern, which focuses on adding new functions

    to an object, whereas a proxy controls access to the object.

    Example

    When loading a large image, you may create some light object to

    represent it until the image is loaded completely. Usually a proxy

    object has the same methods as the object it represents. Once the

    object is loaded, it passes on the actual object. For example,

    abstract class Graphic {public abstract void load();public abstract void draw();

    ...

  • 8/20/2019 Design Pattern QA

    78/171

    }class Image extends Graphic{

    public void load() {...

    }public void draw() {...}...

    }class ImgProxy extends Graphic {

    public void load() {if(image == null) {

    image = new Image(filename);}...

    public void draw() {...

    }...

    }

    Behavioral Patterns 

    a. 

    Chain of Responsibility

    Definition

    Let more than one object handle a request without their knowing

    each other. Pass the request to chained objects until it has been

    handled.

  • 8/20/2019 Design Pattern QA

    79/171

    Where to use & benefits

      One request should be handled by more than one object.

      Don't know which object should handle a request, probably

    more than one object will handle it automatically.

      Reduce coupling.

      Flexible in handling a request.

      Related patterns include

    o  Composite, which a chain of responsibility pattern is often

    applied in conjunction with.

    Example

    The Java Servlet filter framework is an example of chain of

    resposibility design. Note that the chain.doFilter() is the method

    that should be called to make the chain roll. If the subclass missed

    it, the whole chain would be stopped or blocked.

    Java exception handling is another example of chain ofresponsibility design. When an error occurs, the exception call will

    look for a handling class. If there is no handler, the super Exception

    class will be called to throw the exception. Otherwise, the handler

    class will handle it.

    Here comes a simple example, just to show how chain of

    responsibility works. Whenever you spend company's money, you

    need get approval from your boss, or your boss's boss. Let's say, the

    leadership chain is:

    Manager-->Director-->Vice President-->President

  • 8/20/2019 Design Pattern QA

    80/171

    The following is a command line program to check who is

    responsible to approve your expenditure.

    import java.io.*;abstract class PurchasePower {

    protected final double base = 500;protected PurchasePower successor;

  • 8/20/2019 Design Pattern QA

    81/171

    public void setSuccessor(PurchasePower successor){this.successor = successor;

    }

    abstract public voidprocessRequest(PurchaseRequest request);}

    class ManagerPPower extends PurchasePower {private final double ALLOWABLE = 10 * base;

    public void processRequest(PurchaseRequestrequest ) {

    if( request.getAmount() < ALLOWABLE )System.out.println("Manager will

    approve $"+ request.getAmount());else

    if( successor != null)successor.processRequest(request);

    }}

    class DirectorPPower extends PurchasePower {private final double ALLOWABLE = 20 * base;

    public void processRequest(PurchaseRequestrequest ) {

    if( request.getAmount() < ALLOWABLE )System.out.println("Director willapprove $"+ request.getAmount());

    elseif( successor != null)

    successor.processRequest(request);}

    }

  • 8/20/2019 Design Pattern QA

    82/171

    class VicePresidentPPower extends PurchasePower {private final double ALLOWABLE = 40 * base;

    public void processRequest(PurchaseRequestrequest) {

    if( request.getAmount() < ALLOWABLE )System.out.println("Vice President

    will approve $" + request.getAmount());elseif( successor != null )

    successor.processRequest(request);}

    }

    class PresidentPPower extends PurchasePower {private final double ALLOWABLE = 60 * base;

    public void processRequest(PurchaseRequestrequest){

    if( request.getAmount() < ALLOWABLE )System.out.println("President will

    approve $" + request.getAmount());else

    System.out.println( "Your request for$" + request.getAmount() + " needs a boardmeeting!");

    }

    }

    class PurchaseRequest {

    private int number;private double amount;private String purpose;

  • 8/20/2019 Design Pattern QA

    83/171

      public PurchaseRequest(int number, doubleamount, String purpose){

    this.number = number;this.amount = amount;this.purpose = purpose;

    }

    public double getAmount() {return amount;

    }public void setAmount(double amt){

    amount = amt;}

    public String getPurpose() {return purpose;

    }public void setPurpose(String reason) {

    purpose = reason;}

    public int getNumber(){return number;

    }public void setNumber(int num) {

    number = num;}

    }

    class CheckAuthority {public static void main(String[] args){

    ManagerPPower manager = newManagerPPower();

    DirectorPPower director = newDirectorPPower();

  • 8/20/2019 Design Pattern QA

    84/171

      VicePresidentPPower vp = newVicePresidentPPower();

    PresidentPPower president = newPresidentPPower();

    manager.setSuccessor(director);director.setSuccessor(vp);vp.setSuccessor(president);

    //enter ctrl+c to kill.try{

    while (true) {System.out.println("Enter the

    amount to check who should approve yourexpenditure.");

    System.out.print(">");double d = Double.parseDouble(new

    BufferedReader(newInputStreamReader(System.in)).readLine());

    manager.processRequest(newPurchaseRequest(0, d, "General"));

    }}catch(Exception e){

    System.exit(1);}

    }}

    C:\ Command Prompt 

  • 8/20/2019 Design Pattern QA

    85/171

     C:\> javac CheckAuthority.javaC:\> java CheckAuthority

    Enter the amount to check whoshould approve your expenditure.>500Manager will approve $500.0Enter the amount to check whoshould approve your expenditure.>5000

    Director will approve $5000.0Enter the amount to check whoshould approve your expenditure.>11000Vice President will approve$11000.0Enter the amount to check whoshould approve your expenditure.

    >30000Your request for $30000.0 needs aboard meeting!Enter the amount to check whoshould approve your expenditure.>20000President will approve $20000.0Enter the amount to check who

    should approve your expenditure.>C:\>

    You may redo it using interface instead of abstract class.

    The composite pattern is often used with chain of responsibility.

    That means a class may contain the related class that may handle

    the request.

  • 8/20/2019 Design Pattern QA

    86/171

     

    b. Command

    Definition

    Streamlize objects by providing an interface to encapsulate a

    request and make the interface implemented by subclasses in order

    to parameterize the clients.

    Where to use & benefits

      One action can be represented in many ways, like drop-down

    menu, buttons and popup menu.

       Need a callback function, i.e., register it somewhere to be

    called later.

     

    Specify and execute the request at different time   Need to undo an action by storing its states for later retrieving.

      Decouple the object with its trigger

      Easily to be extensible by not touching the old structure.

      Related patterns include

    o  Composite, which aggregates an object. You may

    combine it into a composite command pattern. In general,

    a composite command is an instance of the composite.o  Memento, which keeps state of an object. Command

    supports undo and redo.

    Example

    The simple example of Command pattern is to design a Command

    interface and with an execute method like this:

  • 8/20/2019 Design Pattern QA

    87/171

    public interface Command {public void execute();

    }

    Then, design multiple implementation classes and see how powerful the execute() method has been called dynamically.

    In order to take advantage of Java built-in interfaces, we will design

    a window with a drop down menu, button commands and popup

    menu with command pattern.

    As we know, JButton, JMenuItem and JPopupMenu have

    constructors accept Action type variable. Action interface extends

    ActionListener, which has the following hierarchy.

    public interface EventLister {...

    }

    public interface ActionListener extendsEventListener {

    ...}

    public interface Action extends ActionListener {...

    }

    There is an abstract class called AbstractAction which implementsAction interface. It has the following design.

    public abstract class AbstractAction extendsObject

    implements Action, Cloneable,Serializable

  • 8/20/2019 Design Pattern QA

    88/171

    We will create several command classes to subclass the

    AbstractAction class and pass them to the constructors of JButton,

    JMenuItem and JPopupMenu classes. There is a request method

    called actionPerformed(), every command classes must implementit in order to make it work. To show the concept, we just design

    two actions: submit and exit. You may expand such design to your

    need in your future project.

    Such action can be attached to any component, AWT or Swing.

    The caption, and Icon have been designed as well as tooltips.

    class ExitAction extends AbstractAction {private Component target;public ExitAction(String name, Icon icon,

    Component t){putValue(Action.NAME, name);putValue(Action.SMALL_ICON, icon);putValue(Action.SHORT_DESCRIPTION, name + "

    the program");

    target = t;} public void actionPerformed(ActionEvent evt) {

    int answer =JOptionPane.showConfirmDialog(target, "Are yousure you want to exit? ", "Confirmation",

    JOptionPane.YES_NO_OPTION);

    if ( answer == JOptionPane.YES_OPTION) {System.exit(0);

    }}

    }

    Similar to the above exit action, the submit action is as follows:

    class SubmitAction extends AbstractAction {

  • 8/20/2019 Design Pattern QA

    89/171

      private Component target;public SubmitAction(String name, Icon icon,

    Component t){putValue(Action.NAME, name);putValue(Action.SMALL_ICON, icon);putValue(Action.SHORT_DESCRIPTION, name + "

    the program");target = t;

    } public void actionPerformed(ActionEvent evt) {

    JOptionPane.showMessageDialog(target,"submit action clicked ");

    }}

    You can modify the program to add more commands in. These

    command classes are decoupled from any program. It is very good

    for maintenance.

    The whole workable program is as follows. You can run it to see

    the powerful command design pattern.

    import javax.swing.*;import java.awt.event.*;import java.awt.*;

    class ExitAction extends AbstractAction {private Component target;public ExitAction(String name, Icon icon,

    Component t){putValue(Action.NAME, name);putValue(Action.SMALL_ICON, icon);putValue(Action.SHORT_DESCRIPTION, name + "

    the program");target = t;

    }

  • 8/20/2019 Design Pattern QA

    90/171

      public void actionPerformed(ActionEvent evt) {int answer =

    JOptionPane.showConfirmDialog(target, "Are yousure you want to exit? ", "Confirmation",

    JOptionPane.YES_NO_OPTION);if ( answer == JOptionPane.YES_OPTION) {

    System.exit(0);}

    }}

  • 8/20/2019 Design Pattern QA

    91/171

     class SubmitAction extends AbstractAction {

    private Component target;public SubmitAction(String name, Icon icon,

    Component t){putValue(Action.NAME, name);putValue(Action.SMALL_ICON, icon);putValue(Action.SHORT_DESCRIPTION, name + "

    the program");target = t;

    }public void actionPerformed(ActionEvent evt) {

    JOptionPane.showMessageDialog(target,"submit action clicked ");

    }}

    class Test extends JFrame{Test() {

     Action ea = new ExitAction("Exit", null,

    this);

     Action sa = new SubmitAction("Submit",

    null, this); 

    JMenuBar jbr = new JMenuBar();JMenu dropmenu= new JMenu("File");JMenuItem submitmenu = new JMenuItem(sa);

    JMenuItem exitmenu = new JMenuItem(ea);dropmenu.add(submitmenu);

    dropmenu.add(exitmenu);jbr.add(dropmenu);setJMenuBar(jbr);

    final JPopupMenu pop = newJPopupMenu("PopMenu");

    pop.add(sa);

  • 8/20/2019 Design Pattern QA

    92/171

      pop.add(ea);addMouseListener(new MouseAdapter() {

    public void mousePressed(MouseEvent e){

    showPopup(e);}

    public void mouseReleased(MouseEvent e){

    showPopup(e);}

    private void showPopup(MouseEvent e) {if (e.isPopupTrigger()) {

    pop.show(e.getComponent(),e.getX(),

    e.getY());}

    }

    });JPanel jp = new JPanel();JButton subbtn = new JButton(sa);JButton exitbtn = new JButton(ea);jp.add(subbtn);jp.add(exitbtn);

    Container con = getContentPane();con.add(jp, "South");

    setTitle("Command pattern example");setSize(400,200);setVisible(true);

    }

    public static void main(String[] args) {

  • 8/20/2019 Design Pattern QA

    93/171

      new Test();}

    }java Test

    A windows pops up.

    Pay attention to the action buttons. The instances can be

     parameterized to JButton, JMenuItem and JPopupMenu

    constructors. The powerful action design (Java built-in Action

    interface) makes objects like ExitAction, SubmitAction be used

    everywhere. Design once, use everywhere.

    c. 

    Interpreter

    DefinitionProvides a definition of a macro language or syntax and parsing

    into objects in a program.

    Where to use & benefits

       Need your own parser generator.

      Translate a specific expression.  Handle a tree-related information.

      Related patterns include

    o  Composite, which is an instance in an interpreter.

    o  Flyweight, which shows how to share symbols with

    abstract context.

    o  Iterator , which is used to traverse the tree structure.

  • 8/20/2019 Design Pattern QA

    94/171

    o  Visitor , which is used to maintain behavior of each note in

    tree structure.

    ExampleGiven any string expression and a token, filter out the information

    you want. The below is a simple parser program. the myParser

    method can be used to parse any expression. The composite, visit

    and iterator patterns have been used.

    import java.util.*;

    class Parser{private String expression;private String token;private List result;private String interpreted;

    public Parser(String e, String t) {expression = e;

    token = t;}

  • 8/20/2019 Design Pattern QA

    95/171

      public void myParser() {StringTokenizer holder = new

    StringTokenizer(expression, token);String[] toBeMatched = new

    String[holder.countTokens()];int idx = 0;while(holder.hasMoreTokens()) {

    String item = holder.nextToken();int start = item.indexOf(",");if(start==0) {

    item = item.substring(2);}

    toBeMatched[idx] = item;idx ++;}result = Arrays.asList(toBeMatched);

    }public List getParseResult() {

    return result;}public void interpret() {

    StringBuffer buffer = new StringBuffer();ListIterator list =

    result.listIterator();while (list.hasNext()){

    String token = (String)list.next();if (token.equals("SFO")){

    token = "San Francisco";}else if(token.equals("CA")) {token = "Canada";

    }//...buffer.append(" " + token);

    }interpreted = buffer.toString();

    }

  • 8/20/2019 Design Pattern QA

    96/171

      public String getInterpretedResult() {return interpreted;

    }public static void main(String[] args) {

    String source ="dest='SFO',origin='CA',day='MON'";

    String delimiter = "=,'";Parser parser = new Parser(source,

    delimiter);parser.myParser();parser.interpret();String result =

    parser.getInterpretedResult();System.out.println(result);

    }}java Parserdest San Francisco origin Canada day MON

  • 8/20/2019 Design Pattern QA

    97/171

    d. 

    Iterator

    DefinitionProvide a way to move through a list of collection or aggregated

    objects without knowing its internal representations.

    Where to use & benefits

      Use a standard interface to represent data objects.

      Use s standard iterator built in each standard collection, likeList, Sort, or Map.

       Need to distinguish variations in the traversal of an aggregate.

      Similar to Enumeration class, but more effective.

       Need to filter out some info from an aggregated collection.

      Related patterns include

    o  Composite, which supports recursive structures, whereas

    an iterator is often applied on it.o  Factory Method, which provides appropriate instances

    needed by an iterator subclasses.

    o  Memento, which is often used with an Iterator. The

    iterator stores the memento internally.

    Example

    Employee is an interface, Manager, PieceWorker, HourlyWorker

    and CommissionWorker are implementation classes of interface

    Employee. EmployeeTest class will create a list and use a built-in

    iterator of ArrayList class to traverse the members of the list.

    import java.util.*;interface Employee {

    public abstract double earnings();

  • 8/20/2019 Design Pattern QA

    98/171

    }class Manager implements Employee {

    private double weeklySalary;private String name;public Manager(String name, double s) {

    this.name = name;setWeeklySalary(s);

    }

    void setWeeklySalary(double s) {if (s > 0) {weeklySalary = s;

    } elseweeklySalary = 0;

    }public double earnings() {

    return weeklySalary;}public String getName() {

    return name;}public String toString() {

    return "Manager: " + getName();}

    }

    class PieceWorker implements Employee {

    private double wagePerPiece;private int quantity;private String name;public PieceWorker(String name, double w, int

    q) {this.name = name;setWagePerPiece(w);setQuantity(q);

    }

  • 8/20/2019 Design Pattern QA

    99/171

     void setWagePerPiece(double w) {

    if (w > 0)wagePerPiece = w;

    elsewagePerPiece = 0;

    }

    void setQuantity(int q) {if ( q > 0)

    quantity = q;else

    quantity = 0;}public String getName() {

    return name;}public double earnings() {

    return quantity * wagePerPiece;}

    public String toString() {return "Piece worker: " + getName();

    }}

    class HourlyWorker implements Employee {

    private double hourlyWage;private double hours;private String name;public HourlyWorker(String name, double w,

    double h) {this.name = name;setHourlyWage(w);setHours(h);

    }

  • 8/20/2019 Design Pattern QA

    100/171

     void setHourlyWage(double w) {

    if (w > 0)hourlyWage = w;

    elsehourlyWage = 0;

    }

    void setHours(double h) {if ( 0

  • 8/20/2019 Design Pattern QA

    101/171

      setTotalSales(totalSales);}void setSalary(double s) {

    if( s > 0)salary = s;

    elsesalary = 0;

    }void setCommission(double c) {

    if ( c > 0)commission = c;

    elsecommission = 0;

    }void setTotalSales(double ts) {

    if (ts > 0 )totalSales = ts;

    elsetotalSales = 0;

    }public String getName() {

    return name;}public double earnings() {

    return salary + commission/100*totalSales;}public String toString() {

    return "Commission worker:"+ getName();}

    }

    class EmployeeTest {public static void main(String[] args) {

    java.util.List list = new ArrayList();

    list.add(new Manager("Bill", 800.00));

  • 8/20/2019 Design Pattern QA

    102/171

      list.add(new CommissionWorker("Newt",400.0, 3.75, 159.99));

    list.add(new PieceWorker("Al", 2.5, 200));list.add(new HourlyWorker("Babara", 13.75,

    40));list.add(new Manager("Peter", 1200.00));list.add(new CommissionWorker("Margret",

    600.0,5.5, 200.25));list.add(new PieceWorker("Mark", 4.5,

    333));list.add(new HourlyWorker("William",

    31.25, 50));

    System.out.println("Use built-initerator:");

    Iterator iterator = list.iterator();while(iterator.hasNext()) {

    Employee em =(Employee)iterator.next();

    System.out.print(em + " earns $");System.out.println(em.earnings());

    }}

    }%java EmployeeTestUse built-in iterator:Manager: Bill earns $800.0

    Commission worker:Newt earns $405.999625Piece worker: Al earns $500.0Hourly worker: Babara earns $550.0Manager: Peter earns $1200.0Commission worker:Margret earns $611.01375Piece worker: Mark earns $1498.5Hourly worker: William earns $1562.5

  • 8/20/2019 Design Pattern QA

    103/171

    The above example also shows a dynamic binding feature which is

     popular in Object-Oriented realm.

    If you want to pick up a specific object from the aggregated list,

    you may use the following code.

    while(iterator.hasNext()) {Employee em = (Employee)iterator.next();if (em instanceof Manager) {

    System.out.print(em + " earns $");System.out.println(em.earnings());

    }}

    The above list can also be replaced by an array and achieve the

    same result.

    e. 

    Mediator

    Definition

    Define an object that encapsulates details and other objects interact

    with such object. The relationships are loosely decoupled.

    Where to use & benefits

      Partition a system into pieces or small objects.

      Centralize control to manipulate participating objects(a.k.a

    colleagues)

      Clarify the complex relationship by providing a board

    committee.

      Limit subclasses.

  • 8/20/2019 Design Pattern QA

    104/171

      Improve objects reusabilities.

      Simplify object protocols.

      The relationship between the control class and other

     partic