Design Patterns: Set 2 Design Patterns: Set 2
z
z C C OMPOSITE OMPOSITE z
z O O BSERVER BSERVER
z z A A BSTRACT BSTRACT S S ERVER ERVER z z A A DAPTER DAPTER
z
z B B RIDGE RIDGE z
z P P ROXY ROXY
z z S S TAIRWAY TAIRWAY TO TO H H EAVEN EAVEN
C C OMPOSITE OMPOSITE
««interfaceinterface»» Shape Shape
Square Square Circle Circle
+draw() +draw()
+add(Shape) +add(Shape) +draw() +draw()
Composite Composite Shape Shape
0..*0..*
«delegates»
«delegates»
C C OMPOSITE OMPOSITE and C and C OMMAND OMMAND
zz
Sensor
Sensorand and Command
Command: one: one- -to to- -one association one association
zzC C
OMPOSITEOMPOSITEprovides a way to have one provides a way to have one- -to to- -many many
behaviour without one
behaviour without one- -to to- -many association many association
{{list management and iteration appears only once in list management and iteration appears only once inthe composite class the composite class
zz
Cf. Cf. java.awt.geom.
java.awt.geom.GeneralPathGeneralPath SensorSensor CommandCommand
Composite Composite Command Command
0..*
0..*
O O BSERVER BSERVER
z
z
Service call can be seen as a global event to Service call can be seen as a global event to which the related modules can react which the related modules can react
{
{creator and handler(s) of the event do not have to know creator and handler(s) of the event do not have to know one another
one another →→no direct dependencyno direct dependency z
z
Define an object keeps the data model (Subject) Define an object keeps the data model (Subject)
zzDelegate all ‘view’ functionality to decoupled and Delegate all ‘view’ functionality to decoupled and
distinct Observer objects distinct Observer objects
{
{register to Subject at creationregister to Subject at creation
zz
When Subject changes, it notifies all registered When Subject changes, it notifies all registered Observers
Observers
{{Observer can query Subject for the data that it is Observer can query Subject for the data that it is responsible for monitoring
responsible for monitoring
zz
The number and type of Observers can be The number and type of Observers can be configured dynamically at run time configured dynamically at run time
Synchronous Event
Synchronous Event- -Handling Handling
a = 50%
a = 50%
b = 30%
b = 30%
c = 20%
c = 20%
10 10 10 10 80 80 z z
20 20 30 30 50 50 y y
10 10 30 30 60 60 x x
c c b b a a
Subject Subject
a a bb cc
Observers Observers
change change notifications notifications requests,
requests, modifications modifications
O O BSERVER BSERVER : Pull Model : Pull Model
«
«interfaceinterface»» Observer Observer +update() +update() +register(Observer)
+register(Observer) +unregister(Observer) +unregister(Observer)
#notify()
#notify() Subject
Subject 0..*0..*
+update() +update() Concrete Concrete Observer Observer +getState()
+getState() +setState() +setState() Concrete Concrete Subject Subject
«observes»
«observes»
«registers»
«registers»
O O BSERVER BSERVER : Push Model : Push Model
Observer Observer +update(Message) +update(Message) +register(Observer)
+register(Observer) +unregister(Observer) +unregister(Observer) +notify(Message) +notify(Message) Subject
Subject 0..*0..*
Concrete Concrete Observer Observer +getState()
+getState() +setState() +setState() Concrete Concrete Subject Subject
«observes»
«observes»
«registers»
«registers»
Features Features
z
z
Use Observer when Use Observer when
{{an abstraction has two aspects, one dependent on the an abstraction has two aspects, one dependent on the other
other {
{a change to one object requires changing others, and a change to one object requires changing others, and you do not know how many objects need to be changed you do not know how many objects need to be changed {
{an object should be able to notify other objects without an object should be able to notify other objects without assumptions about these objects
assumptions about these objects
zz
Observer is a widely used pattern: once you Observer is a widely used pattern: once you understand it, you see uses for it everywhere understand it, you see uses for it everywhere
{
{you can register observers with all kinds of objects you can register observers with all kinds of objects rather than writing those objects to explicitly call you rather than writing those objects to explicitly call you zz
Cf. Cf.
{
{java.awt.event.java.awt.event.ActionListenerActionListener
{{java.util.java.util.ObserverObserverand java.util.and java.util.ObservableObservable
A
A BSTRACT BSTRACT S S ERVER ERVER – – A Motivating A Motivating Example
Example
z z Design software for Design software for a simple table a simple table lamp lamp
{{switch: on/off
switch: on/off
{{light: on/offlight: on/off z z The simple design The simple design
violates violates
{{DIP
DIP
{{OCPOCP
Switch Switch
+turnOn() +turnOn() +turnOff() +turnOff() Light Light
Example: A Bad Way to Extend Example: A Bad Way to Extend Switch
Switch
Switch Switch
+turnOn() +turnOn() +turnOff() +turnOff() Light Light
FanSwitch FanSwitch
+turnOn() +turnOn() +turnOff() +turnOff() Fan Fan
Example: Extending Switch with Example: Extending Switch with A A BSTRACT BSTRACT S S ERVER ERVER
«
«interfaceinterface»» Switchable Switchable Switch
Switch
+turnOn() +turnOn() +turnOff() +turnOff() Light Light +turnOn() +turnOn() +turnOff() +turnOff()
+turnOn() +turnOn() +turnOff() +turnOff() FanFan
Who Owns the Interface?
Who Owns the Interface?
z
z Interfaces belong to the client, not to the Interfaces belong to the client, not to the derivative
derivative
{{SwitchSwitch
cannot be deployed without cannot be deployed without Switchable
Switchable {{SwitchableSwitchablecan deployed without Light can deployed without
Lightz z Inheritance hierarchies usually should not Inheritance hierarchies usually should not
be packaged together be packaged together
{{package clients with the interfaces they control
package clients with the interfaces they control z z Cf. Cf.
{
{java.io.java.io.CloseableCloseable,
, java.io.
java.io.FlushableFlushable {{javax.swing.table.javax.swing.table.TableModelTableModel
A A DAPTER DAPTER
z
z Potential SRP violation in A Potential SRP violation in A BSTRACT BSTRACT S
S ERVER ERVER : :
{ {Light Light and Switchable and Switchable may not change may not change for the same reasons
for the same reasons
{ {what if what if Light Light cannot be inherited? cannot be inherited?
z z Solution: add a class that can be Solution: add a class that can be adapted to the interface
adapted to the interface
{ {drawback: extra classes, instantations drawback: extra classes, instantations
Example: Object
Example: Object- -Form Adapter Form Adapter
««interfaceinterface»» Switchable Switchable Switch
Switch
+turnOn() +turnOn() +turnOff() +turnOff() Light Light Adapter Adapter +turnOn() +turnOn() +turnOff() +turnOff()
+turnOn() +turnOn() +turnOff() +turnOff() Light Light
«delegates»
«delegates»
Example: Class
Example: Class- -Form Adapter Form Adapter
«interface«interface»» Switchable Switchable Switch
Switch
+turnOn() +turnOn() +turnOff() +turnOff() Light Light Adapter Adapter +turnOn() +turnOn() +turnOff() +turnOff()
+turnOn() +turnOn() +turnOff() +turnOff() Light Light
B B RIDGE RIDGE – – A Motivating Example A Motivating Example
zz Modelling animal characteristicsModelling animal characteristics {
{each type of animal can have different number of legs (integer)each type of animal can have different number of legs (integer) {
{each type of animal can have different type of movement: fly, waeach type of animal can have different type of movement: fly, walk or lk or crawl
crawl {
{an animal must be able to return the number of legs when askedan animal must be able to return the number of legs when asked {
{an animal must be able to calculate how long it would take to moan animal must be able to calculate how long it would take to move a ve a distance given the type of terrain
distance given the type of terrain z
z Variation in number of legs: a member variable with get/set Variation in number of legs: a member variable with get/set methods
methods z
z Variation in movement type:Variation in movement type:
{
{a member variable to indicate the type and to select different ca member variable to indicate the type and to select different code for ode for movement
movement z
ztight coupling, messy codetight coupling, messy code {
{animal types are derived from a base classanimal types are derived from a base class z
zneed to manage subtypes of animalsneed to manage subtypes of animals zzno animals with more than one type of movementno animals with more than one type of movement z
zsubtyping based on one property; what about classifying them as subtyping based on one property; what about classifying them as mammals, reptiles and birds?
mammals, reptiles and birds?
Example: Bridging Two Hierarchies Example: Bridging Two Hierarchies
z
z Encapsulate the behaviour (i.e. Encapsulate the behaviour (i.e.
movement) into a class movement) into a class z
z The animal class contains an object that The animal class contains an object that has the appropriate behaviour
has the appropriate behaviour
Animal Animal
Bird
Bird ReptileReptile MammalMammal
«delegates»
«delegates»
Movement Movement
Fly
Fly WalkWalk CrawlCrawl +move() +move()
Commonality and Variability Commonality and Variability
z
z
Commonality analysis Commonality analysis
{{what are the common elements among the elementswhat are the common elements among the elements {
{define a family to which the elements belong and a define a family to which the elements belong and a context where things vary
context where things vary {
{find the structure that is unlikely to change over timefind the structure that is unlikely to change over time zz
Variability analysis Variability analysis
{{how things vary within the context of commonality how things vary within the context of commonality (variability only makes sense within a given (variability only makes sense within a given commonality)
commonality) {
{find the structure that is likely to changefind the structure that is likely to change z
z
Shortly: When the type hierarchy has more than Shortly: When the type hierarchy has more than one degree of freedom
one degree of freedom
{{separate the hierarchiesseparate the hierarchies {{tie them together with a bridgetie them together with a bridgeP P ROXY ROXY
z z Allows to cross a barrier without Allows to cross a barrier without either of the participants knowing either of the participants knowing about it
about it { {database database { {network network z
z Theory: P Theory: P ROXY ROXY can be inserted in can be inserted in between two collaborating objects between two collaborating objects without them knowing about it without them knowing about it z z Reality: not so trivial… Reality: not so trivial…
Example: Web Shopping Cart Example: Web Shopping Cart
Order Order Customer
Customer
- -quantityquantity
Item Item --datedate - -statusstatus
-name-name -price-price -sku-sku
Product Product 0..*
0..*
-name-name - -addressaddress - -billingInfobillingInfo
0..*
0..*
Example: Order Proxy Example: Order Proxy
z z Interface that declares all the methods Interface that declares all the methods that clients need to invoke
that clients need to invoke
z z Class that implements those methods Class that implements those methods without knowledge of the database without knowledge of the database z z Proxy that knows about the database Proxy that knows about the database
«
«interfaceinterface»» Order Order
DB
DB OrderOrder DB Proxy
DB Proxy OrderOrder
Implementation Implementation
«delegates»
«delegates»
Example: Order Proxy (cont’d) Example: Order Proxy (cont’d)
public interface public interfaceOrder Order {{
public
public StringStringgetCustomerId();getCustomerId();
public void
public void addItem(addItem(ProductProductp, p, int int quantity);quantity);
public int public int total();total();
} } public class
public class OrderImpOrderImpimplements implements OrderOrder{{ private
private ListList<<ItemItem> itsItems;> itsItems;
public int public int total() {total() {
int int total = 0;total = 0;
for
for ((ItemItemitem : itsItems) item : itsItems)
total += item.getProduct().getPrice() * item.getQuan total += item.getProduct().getPrice() * item.getQuantity();tity();
return return total;total;
} }
/* rest of the implementation omitted */
/* rest of the implementation omitted */
} }
Example: Order Proxy (cont’d) Example: Order Proxy (cont’d)
public class
public classOrderProxyOrderProxyimplements implements OrderOrder{{ public int
public int total() {total() { OrderImp
OrderImp imp = imp = new new OrderImpOrderImp(getCustomerId());(getCustomerId());
ItemData
ItemData[] itemDataArray =[] itemDataArray = DB
DB.getItemsForOrder(orderId);.getItemsForOrder(orderId);
for
for ((ItemDataItemData item : itemDataArray)item : itemDataArray) imp.addItem(
imp.addItem(newnewProductProxyProductProxy(item.sku),(item.sku), item.qty);
item.qty);
return
return imp.total();imp.total();
} }
/* rest of the implementation omitted */
/* rest of the implementation omitted */
} }
S S TAIRWAY TAIRWAY TO TO H H EAVEN EAVEN
z
z Achieves dependency inversion (like Achieves dependency inversion (like P P ROXY ROXY ) )
z z Employs a variation on the class Employs a variation on the class form of A
form of A DAPTER DAPTER z
z Only useful in languages supporting Only useful in languages supporting multiple inheritence
multiple inheritence
z z Completely seperates knowledge of Completely seperates knowledge of the database away from the business the database away from the business rules of the application
rules of the application
S S TAIRWAY TAIRWAY TO TO H H EAVEN EAVEN (cont’d) (cont’d)
Persistent Persistent Object Object
Product Product
Assembly Assembly
+write() +write() +read() +read()
Persistent Persistent Assembly Assembly Persistent Persistent Product Product