19
Composite Design Pattern

Composite Design Pattern. Motivation – Dynamic Structure

Embed Size (px)

Citation preview

Page 1: Composite Design Pattern. Motivation – Dynamic Structure

Composite Design Pattern

Page 2: Composite Design Pattern. Motivation – Dynamic Structure

Motivation – Dynamic Structure

aPicture

aPicture aLine aRectangle

aText aLine aRectangle

Page 3: Composite Design Pattern. Motivation – Dynamic Structure

Motivation – Static Structure

Draw() Add(Graphic) Remove(Graphic) GetChild(int)

Graphic

Draw() Add(Graphic) Remove(Graphic) GetChild(int)

Picture

Draw()

Text

Draw()

Rectange

Draw()

Line

for all g in childreng.Draw()

add g to list of graphics

Page 4: Composite Design Pattern. Motivation – Dynamic Structure

Applicability

• Use the Composite pattern when:– You need to represent part-whole hierarchies of objects– You want clients to ignore the differences between parts

and wholes (individual objects and compositions of objects)

– The compositions are created dynamically – at run time – so use composite:• when you need to build a complex system from primitive

components and previously defined subsystems.• This is especially important when the construction process will

reuse subsystems defined earlier.

Page 5: Composite Design Pattern. Motivation – Dynamic Structure

Structure

Operation() Add(Component) Remove(Component) GetChild(int)

Component

Operation() Add(Component) Remove(Component) GetChild(int)

Composite

Operation()

Leaf_C

Operation()

Leaf_B

Operation()

Leaf_A

for all g in childreng.Operation()

add g to list of components

Page 6: Composite Design Pattern. Motivation – Dynamic Structure

Participants – Plan A

• Component (Graphic)– declares interface for objects in the composition– implements default behavior for the interface common to all

classes, as appropriate– declares an interface for accessing and managing its child

components– (optional) defines an interface for accessing a component’s parent

in the recursive structure, and implements it if that’s appropriate

• Client– manipulates objects in the composition through the Component

interface

Page 7: Composite Design Pattern. Motivation – Dynamic Structure

Participants – Plan A

• Leaf– Represents leaf objects in the composition. A leaf has no

children.– Defines behavior for primitive objects in the composition.

• Composite (picture)– Defines behavior for components having children.– Stores child components.– Implements child-related operations in the Component

interface.

Page 8: Composite Design Pattern. Motivation – Dynamic Structure

Structure

Operation()

Component

Operation() Add(Component) Remove(Component) GetChild(int)

Composite

Operation()

Leaf_C

Operation()

Leaf_B

Operation()

Leaf_A

for all g in childreng.Operation()

add g to list ofcomponents

Page 9: Composite Design Pattern. Motivation – Dynamic Structure

Participants – Plan B

• Component (Graphic)– declares interface for objects in the composition

• Client– manipulates objects in the composition through

the Composite interface

Page 10: Composite Design Pattern. Motivation – Dynamic Structure

Participants – Plan B

• Leaf– Represents leaf objects in the composition. A leaf has no

children.– Defines behavior for primitive objects in the composition.

• Composite (picture)– Defines behavior for components having children.– declares an interface for accessing and managing its child

components – Stores child components.– Implements child-related operations in the Component

interface.

Page 11: Composite Design Pattern. Motivation – Dynamic Structure

Collaborators

• Plan A:Clients use the Component class interface to interact with objects in the composite structure.

• Plan B:Clients use the Composite class interface to interact with objects in the composite structure.

– If the recipient is a Leaf then the request is handled directly.

– If the recipient is a composite, then it usually forwards request to its child components.

Page 12: Composite Design Pattern. Motivation – Dynamic Structure

virtual Operation() virtual Add(node) virtual Remove(node) GetChild(int)

node

Operation() Add(node) Remove(node) GetChild(int)

Tree

for all n in childrenn.Operation()

add n to list of nodes

Tree Structure

Page 13: Composite Design Pattern. Motivation – Dynamic Structure

Consequences

• The Composite pattern:– Defines class hierarchies consisting of primitives and composites– When a client expects a primitive it can also take a composite.– Makes it easier to add new components.

• Newly defined primitives or composites will work automatically with existing structures and client code.

– Can make your design too general.• Since its easy to add new components it is hard to restrict the

components of a composite.• Composite doesn’t support using the type system to support these

constraints for you, since all components have the same base type.

Page 14: Composite Design Pattern. Motivation – Dynamic Structure

14

Directory / File Example – Object Structure

/

bin/ user/ tmp/

file1 file2 subdir/ file3

file4 file5

Composite

Composite Composite Composite

CompositeLeaf Leaf Leaf

Leaf Leaf

• Directory = Composite• File = Leaf

Page 15: Composite Design Pattern. Motivation – Dynamic Structure

15

Directory / File Example – Classes

• One class for Files (Leaf nodes)• One class for Directories (Composite nodes)– Collection of Directories and Files

• How do we make sure that Leaf nodes and Composite nodes can be handled uniformly?– Derive them from the same abstract base class

Leaf Class: File Composite Class: Directory

Page 16: Composite Design Pattern. Motivation – Dynamic Structure

16

Directory / File Example – Structure

Abstract Base Class: Node

Leaf Class: File Composite Class: Directory

Page 17: Composite Design Pattern. Motivation – Dynamic Structure

17

Directory / File Example – Operation

Abstract Base Class: Node size() in bytes of entire directory and sub-directories

Leaf Class: File size () of file

Composite Class: Directory size () Sum of file sizes in this directory and its sub-directories

long Directory::size () { long total = 0; Node* child; for (int i = 0; child = getChild(); ++i; { total += child->size(); } return total;}

Page 18: Composite Design Pattern. Motivation – Dynamic Structure

18

Inventory Example – Problems to Consider

Abstract Base Class: Inventory Item

Leaf Class: Object

Composite Class: Container

Backpack

Cloth Bag Jeweled Dagger

Ruby Ring Wine Bottle

Do you really want all leaf Operations to be defined in Component class?Is Wine Bottle a Composite or does it have an operation for Fill(Liquid)?If Ruby is pried from Dagger, how will this be handled?Would you allow user to put other items in the wine bottle?How do you handle the relative size of items to be placed in a backpack?

Page 19: Composite Design Pattern. Motivation – Dynamic Structure

19

Consequences

• Solves problem of how to code recursive hierarchical part-whole relationships.

• Client code is simplified.– Client code can treat primitive objects and composite

objects uniformly.– Existing client code does not need changes if a new leaf or

composite class is added (because client code deals with the abstract base class).

• Can make design overly general.– Can’t rely on type system to restrict the components of a

composite. Need to use run-time checks.