structural design patterns yaodong bi november 12, 2015november 12, 2015november 12, 2015
TRANSCRIPT
Structural Design PatternsStructural Design Patterns
Yaodong BiYaodong Bi
April 21, 2023April 21, 2023
Structural design patternsStructural design patterns
FaçadeFaçade DecoratorDecorator CompositeComposite ProxyProxy AdapterAdapter BridgeBridge FlyweightFlyweight
FaçadeFaç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
Façade - examplesFaç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.
ClientUse op1(), op2(), op3(), and op4()
ClassBop1_b()op2_b()
ClassCop4_c()
ClassAop3_a()
Façade - Structure
Sequence DiagramSequence Diagram
Client B:ClassB
op1() op1_b()
op4() op4_c()
Facade A:ClassA C:ClassC
op3() op3_a()
op2() op2_b()
framework
BankCustomers
Client
BankCustomersdoDeposit( int amt, Customer cust, Account acc )getBankAccount( Customer cust, int accNum )getBankCustomer( String custName )
BankCustomer BankAccount
CustomergetCustomerName()getNumAccounts()getPersonalNote()getAccount( int )
AccountgetAccountNum()deposit( int )getBalance()
1..n
AccountException
CustomerException
Façade - ExamplesFaçade - Examples
Façade - commentsFaç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
Design Purpose– Add responsibilities to an object at
runtime. Design Pattern Summary
– Provide for a linked list of objects, each encapsulating responsibility.
DecoratorDecorator
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?
Decorator - examplesDecorator - examples
Decorator – structureDecorator – structure
Client
comp
void operation(){ // do actions of the decorator comp.operation(); // do actions of the decorator}
Componentoperation()add(Component)remove(Component)getChild()
ConcreteComp
operation()
DecoratorOperation()
:Decorator1
:Decorator2
:ConcreteComp
Decorator – examplesDecorator – examples
Client
Decorator - Sequence Decorator - Sequence DiagramDiagram
Client :Decorator1
operation() operation()
Component
:Decorator2
:ConcreteComp
operation()
operation()
return
returnreturn
return
1
Decorator – examplesDecorator – examples
:InputStreamReader
System.in:InputStream
: BufferedStreamReader
:Reader
:InputStreamReader
System.in:InputStream
: BufferedStreamReader
Decorator – examplesDecorator – examples
Decorator – key conceptDecorator – key concept
allows addition to and removal from objects at runtime
Decorator – sample codeDecorator – sample code
CompositeComposite
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.
leaf node
non-leaf node
Objects
NonLeafNode
Component
“every object involvedis a Component object”
“non-leaf nodes have one or more
components”
Classes1..n
Composite - structureComposite - structure
NonLeafNodedoIt()
comp
Componentadd( Component )
Remove(component)doIt()
LeafNodedoIt()
TypeANonLeafNodedoIt()
TypeBNonLeafNodedoIt()
1..nClient
for all elements e in comp e.doIt()
Composite - structureComposite - structure
:Client N0:NonLeafNode
N1:NonLeafNode
L1:LeafNode
Composite – A Class DiagramComposite – A Class Diagram
L2:LeafNode L3:LeafNode
N2:NonLeafNode
:Client N0:NonLeafNode
doIt()
N1:NonLeafNode L1:LeafNode
Composite – sequence Composite – sequence diagramdiagram
L2:LeafNodeL3:LeafNodeN2:NonLeafNode
doIt()
doIt()
doIt()
doIt()
doIt()
Component
Composite – examplesComposite – examples
Container
Window … . .
component
1..n
Canvas
CompositeComposite in in java.awtjava.awt
ProxyProxy
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.
BaseActiveClassexpensiveMethod()anotherMethod()
RealActiveClassexpensiveMethod()anotherMethod()
ProxyexpensiveMethod()
anotherMethod()
Client
if ( realActiveObject == null ) // not loaded yet{ realActiveObject = getRealActiveObject(); realActiveObject.expensiveMethod(); } else { realActiveObject.expensiveMethod(); }
Instantiate withProxy object
Proxy – examplesProxy – examples
expensiveMethod()
expensiveMethod()
Proxy – sequence diagramProxy – sequence diagram
BaseActiveClass RealActiveClassProxyClient
create() if needed
GraphicsDisplay()
Imagedisplay()bitmap
ImageProxydisplay()fileName
TexDocgraphics
image
if ( image == null ) { // not loaded yet image = new Image(fileName); }Image.display();
Instantiate withProxy object
Proxy – examplesProxy – examples
Proxy – Sample codeProxy – Sample code
Class TextDoc {Class TextDoc {graphics g;graphics g;TextDoc(ImageProxy ip) {TextDoc(ImageProxy ip) {
g = ip;g = ip;}}void display() {void display() {
g.display();g.display();}}
}}Class ImageProxy implements GraphicsClass ImageProxy implements Graphics { {
FileName fileName;FileName fileName;Image image;Image image;ImageProxy(FileName fn) {ImageProxy(FileName fn) {
fileName = fn;fileName = fn;}}display() {display() { if (image == null) if (image == null)
image = new Image(fileName);image = new Image(fileName); image.display();image.display();}}
}}
Interface Graphics {Interface Graphics {display();display();
}}Class Image Implements GraphicsClass Image Implements Graphics { {
Bitmap bitmap;Bitmap bitmap;Image(FileName fn) {Image(FileName fn) {
bitmap = readImage(fn);bitmap = readImage(fn);}}display() {display() {
// draw the bitmap// draw the bitmap}}readImage(FileName fn) {readImage(FileName fn) {
// read from the file(fn)// read from the file(fn)// create a bitmap// create a bitmap
}}}}
AdapterAdapter
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.
Adapter - examplesAdapter - 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.
Adapter - StructureAdapter - Structure
Client Target+request()
Adapter+request()
Adaptee+requestedMethod();
adaptee.requestedMethod()
adaptee
Adapter – sequence diagramAdapter – sequence diagram
request(TargetIn):TargetOut
Client Target Adapter Adaptee
convert(TargetIn):AdapteeIn
requestedMethod(AdapteeIn):AdapteeOut
convert(AdapteeOut):TargetOutReturn TargetOutReturn TargetOut
request(TargetIn):TargetOut
Adapter – sample codeAdapter – sample code
Interface Target {Interface Target { public TargetOut public TargetOut
request(TargetIn);request(TargetIn);}}
Class Adaptee {Class Adaptee { … … public AdapteeOutpublic AdapteeOut
requestedMethod(AdapteeIn)requestedMethod(AdapteeIn) {{ // produce AdapteeOut;// produce AdapteeOut; return AdapteeOut;return AdapteeOut; }} … …}}
Class Adapter implements Target {Class Adapter implements Target { private private Adaptee adaptee;Adaptee adaptee; public Adapter(public Adapter(AdapteeAdaptee adad) {) { adaptee = adadaptee = ad;; }} public TargetOut request(TargetIn public TargetOut request(TargetIn
ti) {ti) { AdapteeIn ai = convert(ti);AdapteeIn ai = convert(ti); AdapteeOut ao = AdapteeOut ao = adaptee.requestedMethod(ai);adaptee.requestedMethod(ai); return convert(ao);return convert(ao); }} private private AdapteeIn AdapteeIn convert(convert(TargetIn TargetIn
titi) ) {{ // convert // convert TargetInTargetIn to to AdapteeInAdapteeIn }} private private TargetOutTargetOut
convert(convert(AdapteeOutAdapteeOut ao) ao) {{ // convert // convert AdapteeOutAdapteeOut to to
TargetOutTargetOut }}}}
Adapter - commentsAdapter - 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.
Structural Patterns - Structural Patterns - SummarySummary
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