1 / 46

Simplifying Structural Design Patterns with Façade and Decorator

Understand how Façade simplifies interactions with complex systems, and how Decorator adds dynamic responsibilities to objects. Explore examples, structures, sequences, and code samples in Java.

jkieffer
Download Presentation

Simplifying Structural Design Patterns with Façade and Decorator

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Structural Design Patterns Yaodong Bi October 23, 2019

  2. Structural design patterns • Façade • Decorator • Composite • Proxy • Adapter • Bridge • Flyweight

  3. Façade • Design Purpose • Provide a single and simple interface to a package of classes • Design Pattern Summary • Define a single and simple interface for clients to use the functionality of the package

  4. Façade - examples • A compiler package • It normally contains many classes/subpackages like Scanner, Parser, etc. • Most clients only want to compile their programs, i.e., they don’t care about functions of individual components in the package • Use Façade to provide a simple default interface to most clients.

  5. Client Use op1(), op2(), op3(), and op4() Facade op1() op2() op3() op4() Façade - Structure ClassA op3_a() ClassC op4_c() ClassB op1_b() op2_b()

  6. Sequence Diagram Client Facade B:ClassB A:ClassA C:ClassC op1() op1_b() op3() op3_a() op4() op4_c() op2() op2_b()

  7. Client Compiler.compile(“test.c”) Compiler compile() Façade - Structure ProgramNodeBuilder Scanner Parser CodeGenerator

  8. Class Scanner { public Scanner(InputStreamsourcecode) public Token scan() { … } } Class Parser { public parse(Scanner s, ProgramNodeBudiler p) { … } } Class ProgramNodeBuilder { public ProgramNodenewVariable(…) { … } public ProgramNodenewAssignment(…) { … } public ProgramNodenewReturnStmt(…) { … } } Class CodeGenerator { public void visitStatementNode(…) { … } public void visitExpressionNode(…) { … } } Façade – Sample code Class Compiler { public void compile(InputStream sc, OutputStreambytecode) { Scanner sc = new Scanner(sc); ProgramNodeBuilderpnb = new ProgramNodeBuilder(); Parser parser = new Parser(); parser.parse(sc, pnb); IntelCodeGenerator cg = new IntelCodeGenerator(bytecode) ProgramNodenodetree = pnb.getRootNode(); parsetree.traverse(cg); }

  9. Façade - Examples framework Customer getCustomerName() getNumAccounts() getPersonalNote() getAccount( int ) AccountException Account getAccountNum() deposit( int ) getBalance() CustomerException BankCustomers 1..n BankCustomer BankAccount Client BankCustomers doDeposit( int amt, Customer cust, Account acc ) getBankAccount( Customer cust, int accNum ) getBankCustomer( String custName )

  10. Façade - comments • Façade can reduce the degree of dependency between packages • Packages are dependent on each other only through their facades, not individual classes • Use Façade to provide a simple default view of the package that is enough for most clients • Façade does not try to encapsulate/hide the components in the package since there may be clients who need to access individual components in the package

  11. Decorator • Design Purpose • Add responsibilities to an object at runtime. • Design Pattern Summary • Provide for a linked list of objects, each encapsulating responsibility.

  12. Decorator - examples • The word processor example • A text view may have a border and a scroll bar and maybe other bells and whistles attached to it • How can those bells and whistles be added to the text view? • Inheritance?

  13. Decorator – structure Component operation() Client ConcreteComp operation() Decorator Operation() comp void operation() { // do actions of the decorator comp.operation(); // do actions of the decorator }

  14. Decorator - example

  15. Decorator – structure VisualComponent draw() Client TextView draw() Decorator draw() comp comp.draw() ScrollDecorator draw() scrollTo() scrollPosition BorderDescrotor draw() drawBorder() borderWidth super.draw() this.drawBorder()

  16. Decorator – examples Client :Decorator1 :Decorator2 :ConcreteComp

  17. Decorator - Sequence Diagram Client Component :Decorator1 :Decorator2 :ConcreteComp operation() operation() operation() operation() return return return return

  18. Decorator – examples :Reader 1 : BufferedStreamReader :InputStreamReader System.in:InputStream

  19. Decorator – examples : BufferedStreamReader :InputStreamReader System.in:InputStream

  20. Decorator – key concept • allows addition to and removal from objects at runtime

  21. Decorator – sample in Java interface VisualComponent { public void draw(); } public class Decorator implements VisualComponent { private VisualComponent component; public Decorator(VisualComponent comp) { this.component = comp; } public void draw() {component.draw(); } } public class Border extends Decorator { int width = 0; public Border(VisualComponent comp, int width) { super(comp); this.width = width; } public void draw() { System.out.print("Border["+ width + "]"); super.draw(); System.out.print("[" + width + "]Border"); } } public class TextView implements VisualComponent { private String text = null; public void setText(String text) { this.text = text; } public void draw() { System.out.print("--" + text + "--"); } } public class Scroll extends Decorator { public Scroll(VisualComponent stream) { super(stream); } public void draw() { System.out.print("Scroll["); super.draw(); System.out.print("]Scroll"); } }

  22. Decorator – sample in Java public class Driver { public static void main(String[] args) { TextViewtextView = new TextView(); textView.setText("Hello World!"); System.out.println("\n\TEXIVIEW ONLY "); Window window = new Window(textView); window.draw(); System.out.println("\n\nWITH SCROLL "); VisualComponent comp = new Scroll(textView); window.setComponent(comp); window.draw(); System.out.println("\n\nSCROLL + BORDER"); comp = new Border(new Scroll(textView), 3); window.setComponent(comp); window.draw(); } } public class Window { private VisualComponent component; public Window(VisualComponent comp) { this.component = comp; } public void setComponent(VisualComponent comp) { this.component = comp; } public void draw() { component.draw(); } }

  23. Decorator – sample in C++ class VisualComponent { virtual void Draw(); virtual void Resize(); }; Class TextView: public VisualComponet { void draw(0 { // draw } void resize() { // resize }; } class Decorator : public VisualComponent { Decorator(VisualComponent*); void Decorator::Draw () { _component->Draw(); } VisualComponent* _component; }; class BorderDecorator : public Decorator { BorderDecorator(VisualComponent*, int borderWidth); void Draw(){ Decorator::Draw(); DrawBorder(_width); } private void DrawBorder(int); private int _width; }; Class Window { void SetContents(VisualComponent* contents) { // ... } Class Driver { public static void main() { Window* window = new Window(); TextView* textView = new TextView; window->SetContents(textView); Window.draw(); // textview only window->SetContents( new BorderDecorator( new ScrollDecorator(textView), 1 ) ); Window.draw(); // textview with a border // and scrolls. } }

  24. Composite • Design Purpose • Represent a Tree of Objects • Design Pattern Summary • Use a Recursive Form in which the tree class aggregates and inherits from the base class for the objects.

  25. Composite - structure Objects Classes 1..n Component non-leaf node “non-leaf nodes have one or more components” “every object involved is a Component object” leaf node NonLeafNode

  26. Composite - structure Component add( Component ) Remove(component) doIt() 1..n Client comp LeafNode doIt() NonLeafNode doIt() for all elements e in comp e.doIt() TypeANonLeafNode doIt() TypeBNonLeafNode doIt()

  27. Composite – A Class Diagram :Client N0:NonLeafNode N1:NonLeafNode N2:NonLeafNode L3:LeafNode L2:LeafNode L1:LeafNode

  28. Composite – sequence diagram :Client N0:NonLeafNode N1:NonLeafNode L1:LeafNode L2:LeafNode L3:LeafNode N2:NonLeafNode doIt() doIt() doIt() doIt() doIt() doIt()

  29. Composite – examples Component 1..n Composite in java.awt Container component … . . Window Canvas

  30. Proxy • Design Purpose • Avoid the unnecessary execution of expensive functionality in a manner transparent to clients. • Design Pattern Summary • Interpose a substitute class which accesses the expensive functionality only when required.

  31. Proxy – examples Instantiate with Proxy object BaseActiveClass expensiveMethod() anotherMethod() Client Proxy expensiveMethod() anotherMethod() RealActiveClass expensiveMethod() anotherMethod() if ( realActiveObject == null ) // not loaded yet { realActiveObject = getRealActiveObject(); realActiveObject.expensiveMethod(); } else { realActiveObject.expensiveMethod(); }

  32. Proxy – sequence diagram Client BaseActiveClass Proxy RealActiveClass expensiveMethod() create() if needed expensiveMethod()

  33. Proxy – examples Instantiate with Proxy object Graphics Display() TexDoc graphics Image display() bitmap ImageProxy display() fileName image if ( image == null ) { // not loaded yet image = new Image(fileName); } Image.display();

  34. Class TextDoc { graphics g; TextDoc(Graphics ip) { g = ip; } void display() { g.display(); } } Class ImageProxy implements Graphics { FileNamefileName; Image image; ImageProxy(FileNamefn) { fileName = fn; } display() { if (image == null) image = new Image(fileName); image.display(); } } Proxy – Sample code Interface Graphics { display(); } Class Image Implements Graphics { Bitmap bitmap; Image(FileName fn) { bitmap = readImage(fn); } display() { // draw the bitmap } readImage(FileName fn) { // read from the file(fn) // create a bitmap } }

  35. Adapter • Design Purpose • Allow an application to use external functionality in a retargetable manner. • Design Pattern Summary • Write the application against an abstract version of the external class; introduce a subclass that aggregate the external class.

  36. Adapter - examples • Interact with legacy systems • When you design a new system which has to interact with a legacy system, you may not want to the new system tightly coupled with (or dependent upon) the legacy system since the legacy system may be replaced in the future. • Using 3rd party systems • You may want to be able to easily substitute the current 3rd party system with another one.

  37. Class Adapter

  38. Client Object Adapter - Structure Target +request() Adaptee +requestedMethod(); adaptee Adapter +request() adaptee.requestedMethod()

  39. Adapter – sequence diagram Client Target Adapter Adaptee request(TargetIn):TargetOut request(TargetIn):TargetOut convert(TargetIn):AdapteeIn requestedMethod(AdapteeIn):AdapteeOut Return TargetOut Return TargetOut convert(AdapteeOut):TargetOut

  40. Object Adapter – sample code Interface Target { public TargetOut request(TargetIn); } Class Adaptee { … public AdapteeOut requestedMethod(AdapteeIn) { // produce AdapteeOut; return AdapteeOut; } … } Class Adapter implements Target { private Adapteeadaptee; public Adapter(Adapteead) { adaptee = ad; } public TargetOut request(TargetInti) { AdapteeInai = convert(ti); AdapteeOutao = adaptee.requestedMethod(ai); return convert(ao); } private AdapteeInconvert(TargetInti) { // convert TargetIn to AdapteeIn } private TargetOut convert(AdapteeOutao) { // convert AdapteeOut to TargetOut } }

  41. DrawingTool Object Adapter - Example Shape +boundingBox() +createManipulator() TextView +getExtent(); text TextShape +boundingBox() +createManipulator() text.getExtent() return new TextManipulator()

  42. Design for Adaption • Pluggable Adapters • A small set of operations is specified for adapter & adaptee to implement • Using Abstract Operations • Client and target are the same entity • Adapter overrides abstract operations to delegate operations to adaptee • Using Delegate Objects • A delegate interface specifies operations the adapter needs to implement

  43. Using Abstract Operations

  44. Using Delegate Objects

  45. Adapter - comments • An adapter may have more than one adaptee • There may not be a one-to-one correspondence between operations of Target and those of Adaptee • So it is possible that an operation of Target is realized with two separate adaptee classes. • The pattern decouples Client from adaptee. • When a different adaptee is needed, we only need to change to another adapter and the client does not need to change at all.

  46. Structural Patterns - Summary • Facade provides an interface to collections of objects • Decorator adds to objects at runtime • Composite represents trees of objects • Proxy avoids calling expensive operations unnecessarily • Adapter decouples client from an existing system

More Related