1 / 14

The Composite Design Pattern

The Composite Design Pattern. aComposite. Example : complex graphic application, with hierarchically nested objects. Main idea : Containers and leaf objects appear the same to clients. Up and down delegation : A container may delegate to all contained objects.

baruch
Download Presentation

The Composite Design Pattern

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. The Composite Design Pattern aComposite • Example: complex graphic application, with hierarchically nested objects. • Main idea: Containers and leaf objects appear the same to clients. • Up and down delegation: • A container may delegate to all contained objects. • A leaf/container may delegate to containing objects. aLeaf aComposite aLeaf aLeaf aLeaf aLeaf

  2. Composite pattern - motivation Graphic Draw() Add(Graphic) Remove(Graphic) GetChild(int) graphics Picture Rectangle Text Line forall g in graphics Draw( ) Draw( ) Draw( ) Draw( ) g.Draw() Add(Graphic g) Remove(Graphic) GetChild(int) add g to list of graphics

  3. Composite Class Diagram Graphic Draw() Add(Graphic) Remove(Graphic) GetChild(int) graphics Picture Rectangle Text Line forall g in graphics Draw( ) Draw( ) Draw( ) Draw( ) g.Draw() Add(Graphic g) Remove(Graphic) GetChild(int) add g to list of graphics

  4. Composite object structure aComposite aLeaf aComposite aLeaf aLeaf aLeaf aLeaf

  5. Composite: General Class Diagram • Component (Graphic) • declares interface for objects in the composition • implements default behavior • declares an interface for accessing and managing its child components • (optional) declares an interface for accessing a component’s parent • Leaf (Rectangle, Line, Text etc.) • 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 • Client • manipulates objects in the composition through the Component interface Component Operation() Add(Component) Remove(Component) GetChild(int) children Composite Client Operation() forall g in children Add(Component) g.Operation() Remove(Component) GetChild(int) Leaf Operation()

  6. Participants • Component (Graphic) • declares interface for objects in the composition • implements default behavior • declares an interface for accessing and managing its child components • (optional) declares an interface for accessing a component’s parent • Leaf (Rectangle, Line, Text etc.) • 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 • Client • manipulates objects in the composition through the Component interface

  7. Implementation • Explicit parent references • define the parent reference in the Component class • essential to maintain the invariant that all children of a composite have as their parent the composite that in turn has them as children • easiest way to ensure - change the component’s parent only when it’s being added or removed from composite • Sharing components • multiple parents • ambiguities as a request propagates up the structure

  8. Implementation: Maximizing the Component interface • Goal: clients must be unaware of a specific Leaf or Composite classes they are using • To attain the goal:Component class should define as many common operations as possible • The goal sometimes conflict with the principle of class hierarchy design: “A class should only define operations that are meaningful for its subclasses” • Definition of the interface for accessing the children in Component seems inapplicable for leaves • But, • we can see a Leaf as a Component that never has children • a default operation for child access in the Component class that never returns any children

  9. Implementation (3/4) • Declaring the child management operations • Trade-off between safety and transparency • Declare these operations in Component and make them meaningful for Leaf classes • all components are treated uniformly (transparency) • clients may try to do meaningless operations like add and remove object from leaves (costs safety) • Declare these operations in Composite • any attempt to add/remove children from leaves will be caught at compile time (safety) • transparency is lost • Should component implement a list of Components • space penalty for every leaf • better implement the list in Composite • Child ordering • Iterators!

  10. Implementation (4/4) • Who will delete components? • Make a Composite responsible for deleting its children when it’s destroyed • Exception: when leaves are immutable and can be shared

  11. Composite pattern - implementation • Explicit parent references • define the parent reference in the Component class • essential to maintain the invariant that all children of a composite have as their parent the composite that in turn has them as children • easiest way to ensure - change the component’s parent only when it’s being added or removed from composite • Sharing components • multiple parents • ambiguities as a request propagates up the structure

  12. More Implementation Issues • Maximizing the Component interface • Goal: clients must be unaware of a specific Leaf or Composite classes they are using • To attain the goal:Component class should define as many common operations as possible • The goal sometimes conflict with the principle of class hierarchy design: “A class should only define operations that are meaningful for its subclasses” • Definition of the interface for accessing the children in Component seems inapplicable for leaves • But, • we can see a Leaf as a Component that never has children • a default operation for child access in the Component class that never returns any children

  13. Issues • Declaring the child management operations • Trade-off between safety and transparency • Declare these operations in Component and make them meaningful for Leaf classes • all components are treated uniformly (transparency) • clients may try to do meaningless operations like add and remove object from leaves (costs safety) • Declare these operations in Composite • any attempt to add/remove children from leaves will be caught at compile time (safety) • transparency is lost • Should component implement a list of Components • space penalty for every leaf • better implement the list in Composite • Child ordering • Iterators! • Who will delete components? • Make a Composite responsible for deleting its children when it’s destroyed • Exception: when leaves are immutable and can be shared

  14. Composite pattern - structure Component Operation() Client Add(Component) Remove(Component) forall g in children GetChild(int) g.Operation() children Composite Leaf Operation() Operation() Add(Component) Remove(Component) GetChild(int)

More Related