Introduction to Design Pattern

Information about Introduction to Design Pattern

Published on February 14, 2008

Author: Simeone

Source: authorstream.com

Content

Introduction to Design Pattern: Introduction to Design Pattern Sammy Wang CS, UGA Gang of Four Design Patterns: Gang of Four Design Patterns Behavioral patterns Chain of responsibility Command Interpreter Iterator Mediator Memento Observer State Strategy Template method Visitor Creational patterns Abstract factory Builder Factory method Prototype Singleton Structural patterns Adapter Bridge Composite Decorator Facade Flyweight Proxy General Principles: General Principles The Single-Responsibility Principle (SRP) The Interface-Segregation Principle (ISP) The Open-Closed Principle (OCP) The Liskov Substitution Principle (LSP) The Single-Responsibility Principle (SRP): The Single-Responsibility Principle (SRP) “A class should have only one reason to change” Why? Every responsibility is an axis of change. The change will be manifest/cascade An Example of SRP Violation : Modem.java Interface Modem { public void dial(String pno); public void hangup(); public void send(char c); public char recv(); } An Example of SRP Violation Two responsibilities: Connection management: dial and hangup Communication management: send and recv Refactoring: Refactoring <<interface>> Connection +dial(pno:String) +hangup() <<interface>> Data Channel +send(:char) +recv() Modem Implementation Another Example of SRP Violation: Another Example of SRP Violation Persistence Subsystem Employee +calculatePay +Store The Interface-Segregation Principle (ISP): The Interface-Segregation Principle (ISP) It deals with “fat” interface—Interface Contamination. Different client needs different services– Customized Service The Interface-Segregation Principle (ISP): The Interface-Segregation Principle (ISP) Client1 Client2 <<interface>> Service1 +m1() +p2() <<interface>> Service2 +m2() +p1() Service Service includes public function: m1(), m2(), p1(), p2() An Example of ISP Violation: An Example of ISP Violation Client -indexCursor Indexer -searcher Searcher <<interface>> BadExample +first() void +last() void +next() void +previous() void +getExcerpt() String +getFullRecord() String +reIndexAll() void +updateIndex() void +search(keywords String[]) void +getResult() void Refactoring: Refactoring Client -indexCursor Indexer -searcher Searcher <<interface>> Indexer +reIndexAll() void +updateIndex() void <<interface>> Searcher +search(keywords String[]) void +getResult() void FileIndexer +reIndexAll() void +updateIndex() void RdbIndexer +reIndexAll() void +updateIndex() void <<interface>> ResultSet +first() void +last() void +next() void +previous() void +getExcerpt() String +getFullRecord() String Interface can’t be instantiated The Open-Closed Principle (OCP): The Open-Closed Principle (OCP) Software entities (classes, modules, functions, etc) should be open to extension, but closed for modification Principle of Encapsulation of Variation (EVP) "Open For Extension" – extend/change the behavior of the module as the requirements change "Closed For Modification" - Extending the behavior of the module does not result in the changing of the source code or binary code of the module itself. An Example of OCP Violation: An Example of OCP Violation Client is not open and closed: Client Server1 Server2 Refactoring: Refactoring STRATEGY pattern: Client is both open and closed (open to extension and closed for modification) Abstraction is the key Client <<interface>> Client Interface Server The Liskov Substitution Principle (LSP): The Liskov Substitution Principle (LSP) “Subtypes must be substitutable for their base types” Whenever a method accepts a base type, it must accept the base type’s derived class. For example: If method1(Base base), Then method1(Derived derived) Base base Derived derived Tester +method1(Base) Rectangle vs. Square: Rectangle vs. Square Rectangle.java public class Rectangle{ private long width; private long height; public void setWidth(long width){ this.width = width; } public long getWidth(){ return this.width; } public void setHeight(long height){ this.height = height; } public long getHeight(){ return this.height; } } Square.java public class Square{ private long side; public void setSide(long side){ this.side = side; } public long getSide(){ return side; } } Rectangle width: long height: long Square side: int Rectangle vs. Square: Rectangle vs. Square Rectangle width: long height: long Square width: long height: long side: int public class Square extends Rectangle{ private long side; private long height; public void setWidth(long width){ setSide(width); } public long getWidth(){ return getSide(); } public void setHeight(long height){ setSide(height); } public long getHeight(){ return getSide(); } public long getSide(){ return side; } public void setSide(long side){ this.side = side; } } Problem: Problem Rectangle width: long height: long Square width: long height: long side: int Tester +resize void Tester.java public class Tester{ public void resize(Rectangle r){ while(r.getHeight() < r.getWidth() ) r.setWidth(r.getWidth() +1 ); } Refactoring: Refactoring <<interface>> Quadrangle width:long height:long Square side:long width:long height:long Ractangle width:long height:long Quardrangle.java public interface Quardrangle{ public long getWidth(); public long getHeight(); } Inheritance from abstraction, not from implementation Source code: Source code Rectangle.java public class Rectangle implements Quadrangle{ private long width; private long height; public void setWidth(long width){ this.width = width; } public long getWidth(){ return this.width; } public void setHeight(long height){ this.height = height; } public long getHeight(){ return this.height; } } Square.java public class Square implements Quadrangle{ private long side; public void setSide(long side){ this.side = side; } public long getSide(){ return side; } public long getWidth(){ return getSide(); } public long getHeight(){ return getSide(); } } Factories: Factories Creates Creates Creates Creates Simple Factory Factory Pattern Abstract Factory Simple Factory: Simple Factory <<interface>> Fruit +grow:void +harvest:void +plant:void Grape +grow:void +harvest:void +plant:void seedless:boolean Apple +grow:void +harvest:void +plant:void treeAge:boolean Strawberry +grow:void +harvest:void +plant:void FruitGardener +factory:Fruit Source Code: Source Code FruitGardener.java Public class FruitGardener{ Public static Fruit factory(String which){ if(which.equalsIgnoreCase(“apple”)) { return new Apple(); } if(which.equalsIgnoreCase(“strawberry”)) { return new Strawberry(); } if(which.equalsIgnoreCase(“grape”)) { return new grape(); } else throw new Exception(“no such fruit”); } } Factory: Factory <<interface>> FruitGardener +factory: Fruit AppleGardener +factory: Fruit Strawberry Gardener +factory: Fruit GrapeGardener +factory: Fruit <<interface>> Fruit +grow:void +harvest:void +plant:void Apple +grow:void +harvest:void +plant:void Strawberry +grow:void +harvest:void +plant:void Grape +grow:void +harvest:void +plant:void Creates Sequence Diagram: Sequence Diagram :Client :AppleGardener :Apple new new Factory() Apple Client.java: Public class Client{ Private static Fruit apple,grape; Private static FruitGardener aG, gG; Public static void main(String[] args){ aG = new AppleGardener(); apple = aG.factory(); gG = new GrapeGardener(); Grape = gG.factory(); } } Abstract Factory: Abstract Factory Garden Example: Garden Example <<interface>> Gardener <<interface>> Fruit TropicalGardener +createFruit:Fruit +createVeggie:Veggie TropicalFruit +TropicalFruit name:String NorthenGardener +createFruit:Fruit +createVeggie:Veggie NorthernFruit +NorthernFruit name:String <<interface>> Veggie TropicalVeggie +TropicalVeggie name:String NorthernVeggie +NorthernVeggie name:String Creates Creates Source Code1: Source Code1 Interface Gardener: public interface Gardener{} NorthernGardener.java: public class NorthernGardener implements Gardener{ public Fruit createFruit(String name){ return new NorthernFruit(name); } public Veggie createVeggie(String name){ return new NorthernVeggie(name); } } TropicalGardener.java: public class TropicalGardener implement Gardener{ public Fruit createFruit(String name){ return new TropicalFruit(name); } public Veggie createVeggie(String name){ return new TropicalVeggie(name); } } Source Code2: Source Code2 interface Veggie: public interface Veggie{} NorthernVeggie.java: public class NorthernVeggie(String name){ private String name; public NorthernVeggie(String name){ this.name = name;} public String getName(){ return name; } public void setName(String name){ this.name = name; } } TropicalVeggie.java: public class TropicalVeggie(String name){ private String name; public TropicalVeggie(String name){ this.name = name;} public String getName(){ return name; } public void setName(String name){ this.name = name; } } interface Fruit: public interface Fruit{} Northern Fruit.java: public class NorthernFruit(String name){ private String name; public NorthernFruit(String name){ this.name = name;} public String getName(){ return name; } public void setName(String name){ this.name = name; } } TropicalFruit.java: public class TropicalFruit(String name){ private String name; public TropicalFruit(String name){ this.name = name;} public String getName(){ return name; } public void setName(String name){ this.name = name; } } Another Example: Another Example WinFactory +createButton: Void +createMenu: Void OSXFactory +createButton: Void +createMenu: Void <<interface>> Button +paint:void Creates <<interface>> GUIFactory + createButton:void WinButton Creates OSXButton <<interface>> Menu WinMenu OSXMenu Source Code: Source Code /* * GUIFactory example */ public abstract class GUIFactory { public static GUIFactory getFactory() { int sys = readFromConfigFile("OS_TYPE"); if (sys == 0) { return(new WinFactory()); } else { return(new OSXFactory()); } } public abstract Button createButton(); } class WinFactory extends GUIFactory { public Button createButton() { return(new WinButton()); } } class OSXFactory extends GUIFactory { public Button createButton() { return(new OSXButton()); } } public abstract class Button { private String caption; public abstract void paint(); public String getCaption(){ return caption; } public void setCaption(String caption){ this.caption = caption; } } class WinButton extends Button { public void paint() { System.out.println("I'm a WinButton: “ +caption); } } class OSXButton extends Button { public void paint() { System.out.println("I'm a OSXButton: “ +caption); } } public class Application { public static void main(String[] args) { GUIFactory aFactory = GUIFactory.getFactory(); Button aButton = aFactory.createButton(); Menu aMenu = aFactory.createMenu(); aButton.setCaption("Play Button"); aButton.paint(); aMenu.setCaption("Play Menu"); aMenu.paint(); } //output is I'm a WinButton: Play Button I'm a WinMenu: Play Menu OR I'm a OSXButton: Play Button I'm a OSXMenu: Play Menu Composite Design Pattern: Composite Design Pattern This pattern allows a client object to treat both single components and collections of components identically: file system recursive AWT & SWING Bi-direction, leaf holds reference to composite Cache leaf to enhance performance Two variation: transparent pattern and safe pattern Safety Style Class Diagram: Safety Style Class Diagram Composite +defaultMethod() +getChild() +addComponent +removeComponent Leaf +defaultMethod() <<interface>> Component +defaultMethod() 0..* Client aComponent: Component Source Code: Source Code import java.util.*; interface Component { public String defaultMethod(); public ArrayList<Component> getChildren(); public boolean addComponent(Component c); public boolean removeComponent(Component c); } class Composite implements Component { private String id; private ArrayList<Component> components = new ArrayList<Component>(); public Composite(String identification) { id = identification; } public String defaultMethod(){ String s = "(" + id + ":"; for (Component child : getChildren()) s = s + " " + child.defaultMethod(); return s + ")"; } public ArrayList<Component> getChildren(){ return components; } public boolean addComponent(Component c) { return components.add(c); } public boolean removeComponent(Component c) { return components.remove(c); } } class Leaf implements Component { private String id; public Leaf(String identification) { id = identification; } public String defaultMethod() { return id; } } class CompositePattern { public static void main(String[] args) { Composite england = new Composite("England"); Leaf york = new Leaf("York"); Leaf london = new Leaf("London"); england.addComponent(york); england.addComponent(london); england.removeComponent(york); Composite france = new Composite("France"); france.addComponent(new Leaf("Paris")); Composite europe = new Composite("Europe"); europe.addComponent(england); europe.addComponent(france); System.out.println( europe.defaultMethod() ); } } //output: (Europe: (England: London) (France: Paris)) Transparent Style Class Diagram: Transparent Style Class Diagram Client aComponent: Component <<interface>> Component +defaultMethod() +getChild() +addComponent +removeComponent 0..* Composite +defaultMethod() +getChild() +addComponent +removeComponent class Leaf implements Component { private String id; public Leaf(String identification) { id = identification; } public String defaultMethod() { return id; } public ArrayList<Component> getChildren() { return null; } public boolean addComponent(Component c) { return false; } public boolean removeComponent(Component c) { return false; } } Another Safety Style Example: Another Safety Style Example Graphics +draw:void Line +draw:void Rectangle +draw:void Circle +draw:void Picture -list:Vector +draw:void +add:void +remove:void +getChild:Graphics Source Code: Source Code abstract public class Graphics{ public abstract void draw(); } public class Picture extends Graphics{ private Vector<Graphics> list; list = new Vector(10); public void draw(){ for(int i=0;i<list.size();i++){ Graphics g=list.get(i); g.draw(); } } public void add(Graphics g){ list.add(g); } public void remove(Graphics g){ list.remove(g); } public Graphics getChild(int i){ return list.get(i); } } public class Line extends Graphics{ public void draw(){ //code for drawing line }} public class Rectangle extends Graphics{ public void draw(){ //code for drawing rectangle }} public class Circle extends Graphics{ public void draw(){ //code for drawing circle }} The Strategy Pattern: The Strategy Pattern Define a family of algorithms, encapsulate each one, and make them interchangeable. It lets the algorithm vary independently from clients that use it. – [GOF] It embodies two principles—encapsulate the concept that varies and program to an interface, not an implementation. loosely coupled collection of interchangeable parts vs. monolithic, tightly coupled system extensible, maintainable, and reusable if/else problem Strategy: behavior/dynamic vs. Bridge: static Class Diagram: Class Diagram Pros and Cons: Pros and Cons Moving the common code from detailed strategy class to its base abstract class Hiding complex detail information from client Client decides to use which strategy dynamically Sort Sample: Sort Sample Sorter/Client +sort:void +add(String):void +setSortStrategy: SortStrategy BubbleSort +sort:void HeapSort +sort:void QuickSort +sort:void SortStrategy +sort:void How to Invoke: How to Invoke static void Main( { Sorter studentRecords = new Sorter();studentRecords.add("Samual");studentRecords.add("Jimmy");studentRecords.add("Sandra");    studentRecords.setSortStrategy(new QuickSort());studentRecords.sort();studentRecords.SetSortStrategy(new HeapSort());studentRecords.sort();   } Discount Sample: Discount Sample Client NoDiscount -price:double -copies:int +NoDiscount +caclDiscount:double FlatRate -price:double -copies:int +NoDiscount +caclDiscount:double amount:double Percentage -price:double -copies:int +NoDiscount +caclDiscount:double percent:double DiscountStrategy +caclDiscount:double Source Code: Source Code public abstract class DiscountStrategy{ private single price = 0; private int copies = 0; public abstract single calcDiscount(); public DiscountStrategy(single price, int copies){ this.price = price; this.copies = copies; } } public class NoDiscount extends DiscountStategy{ private single price = 0; private int copies = 0; public NoDiscount (single price, int copies){ this.price = price; this.copies = copies; } public single calcDiscount(){ return 0; } } public class Percentage extends DiscountStategy{ private single percent; private single price = 0; private int copies = 0; public Percentage (single price, int copies){ this.price = price; this.copies = copies; } public single getPercentage(){ return percent; } public void setPercentage(single percent){ this.percent = percent; } public single calcDiscount(){ return copies*price*percent; } } public class Client{ public static void main(String[] args) { DiscountStrategy a=new Percentage( 100,1000); a.setPercentage(0.1); double discount=a.calcDiscount(); } If/Else Problem: If/Else Problem public class Client{ private int copies; private double price; private String discountType; private double amount; private double percent; public double calcDiscount(String discountType, int copies, double price) { if(discountType.equals(“NoDiscount”) return copies*price; else( if(discountType.equals(“FlatDiscount”) return copies*price-amount; else( if(discountType.equals(“PercentageDiscount”) … …} } Decorator Design Pattern: Decorator Design Pattern Wrapping the new "decorator" object around the original object typically by passing the original object as a parameter to the constructor of the decorator, with the decorator implementing the new functionality. the interface of the original object needs to be maintained by the decorator. Transparent vs. semi-transparent style Decorator: adding new behavior at runtime vs. subclassing: adding new behavior at compile time Class Diagram: Class Diagram Concrete Component Decorator Sequence Diagram: Sequence Diagram Original Class Java I/O Decorator: Java I/O Decorator Reader +read() FileReader +read() BufferedReader +read() +readLine() LineNumberReader +read() +readLine() +getLineNumber() Sequence Diagram: Sequence Diagram Slide 51: import java.io.BufferedReader;import java.io.FileReader; import java.io.LineNumberReader; public class Tester { public static void main(String args[]) { read("c:\\result.xml"); } public static void read(String filename) { try { FileReader frdr = new FileReader(filename); BufferedReader brdr = new BufferedReader(frdr); LineNumberReader lrdr = new LineNumberReader(brdr); //Reader rdr = new LineNumberReader(brdr); for(String line; (line = lrdr.readLine()) != null;) { //rdr.read(); //read a single character System.out.print(lrdr.getLineNumber() + ":\t"); printLine(line); } } catch(java.io.FileNotFoundException fnfx) { fnfx.printStackTrace(); } catch(java.io.IOException iox) { iox.printStackTrace(); } } private static void printLine(String s) { for(int c, i=0; i < s.length(); ++i) { c = s.charAt(i); if(c == '\t') System.out.print(" "); else System.out.print((char)c); } System.out.println(); } } References: References Agile Software Development by Robert C. Martin Gang of Four Design Patterns Design Patterns by Yanhong http://www.tml.tkk.fi/~pnr/GoF-models/html/ http://en.wikipedia.org/wiki/Image:Abstract_factory_UML.svg http://en.wikipedia.org/wiki/Composite_pattern http://en.wikipedia.org/wiki/Decorator_pattern http://www.javaworld.com/cgi-bin/mailto/x_java.cgi

Related presentations


Other presentations created by Simeone

Erikson and Horney
15. 01. 2008
0 views

Erikson and Horney

Sudden Illnesses 9
14. 01. 2008
0 views

Sudden Illnesses 9

Customer loyalty presentaion
15. 03. 2008
0 views

Customer loyalty presentaion

topic5 ravi
10. 01. 2008
0 views

topic5 ravi

cloning
15. 01. 2008
0 views

cloning

aecma
16. 01. 2008
0 views

aecma

Tox Made Simple
18. 01. 2008
0 views

Tox Made Simple

NEO YOUNG CREATIVE AWARD 2007
04. 02. 2008
0 views

NEO YOUNG CREATIVE AWARD 2007

GLJ Mobile Logistics121207
04. 02. 2008
0 views

GLJ Mobile Logistics121207

CohenLevesque
07. 02. 2008
0 views

CohenLevesque

pring
11. 02. 2008
0 views

pring

Ancient Cosmetic toxicology
10. 01. 2008
0 views

Ancient Cosmetic toxicology

1stReviewppt
25. 01. 2008
0 views

1stReviewppt

newsfile469 1
28. 01. 2008
0 views

newsfile469 1

15 Comets
16. 01. 2008
0 views

15 Comets

imci c slides
25. 02. 2008
0 views

imci c slides

Friday
28. 02. 2008
0 views

Friday

delta 2
09. 01. 2008
0 views

delta 2

Safetyprogram
05. 03. 2008
0 views

Safetyprogram

2 20071224184840
11. 03. 2008
0 views

2 20071224184840

websearch
19. 03. 2008
0 views

websearch

schreffler hopkins
21. 03. 2008
0 views

schreffler hopkins

CKtrain green
15. 01. 2008
0 views

CKtrain green

era2
03. 04. 2008
0 views

era2

mother100703
09. 01. 2008
0 views

mother100703

dahlbom
21. 01. 2008
0 views

dahlbom

Comics and Mangas
18. 02. 2008
0 views

Comics and Mangas

AMC Online Trip Listings
06. 02. 2008
0 views

AMC Online Trip Listings

CPZvezda Brus
22. 01. 2008
0 views

CPZvezda Brus