# The Composite Pattern

Λογισμικό & κατασκευή λογ/κού

2 Δεκ 2013 (πριν από 5 χρόνια και 2 μήνες)

229 εμφανίσεις

The Composite Pattern

SE
-
2811

Dr. Mark L. Hornick

1

Composite Pattern context

Graphics drawing
applications

Renders graphic
primitives (e.g.
lines
,
rectangles
,
ellipses
,…)

But also
subdrawings

(e.g.
groups
of
primitives
can be
translated, rotated, or scaled
as a
unit)

Hmm…does this sound like an upcoming lab??

User
-

A

can have
-
items
.

Each
-
item

can in turn be a

(sub
-

Generally, any app implementing a hierarchical structure

A object can contain many sub
-
objects

Each sub
-
object can in turn contain an object.

Q
: Do any Swing classes implement a similar hierarchy???

The Composite Pattern is applied in
situations involving object
heirarchies

The problem

A collection of objects forms a hierarchy

Each object may be

An
individual (primitive, leaf, or
part
)
object

A composition of other
objects (
composite
)

We want to treat all objects uniformly

No special treatment
(
if,
instanceof
) for
composite objects (sub
-
drawings or sub
-

Solution

Compose objects
into
recursive tree
structures via the
Composite Pattern

The Composite Pattern allows you to
compose objects into tree structures to
represent part
-
whole hierarchies

aComposite

aComposite

aPart

aPart

aPart

aPart

aPart

aPart

This pattern allows clients to treat
individual objects (
Parts
) and
compositions of objects
(
Composites
) uniformly.

Example

computer

System Unit

monitor

You want to build a new computer.
Let’s configure the computer as a
system of hierarchical components.

HDD

Cabinet

Chassis

CPU

keyboard

Memory

GPU

Fan

Motherboard

composite

part

Composite Pattern class diagram
and key classes/interfaces

SE
-
2811

Dr. Mark L. Hornick

6

Client app

ClientApp

uses the
Component

Interface

to
manipulate objects
in the composition
by calling
(),
remove
(), and
context
-
specific
operations.

Component

defines an
interface
(or abstract class)

for all objects: both
Leaf

and
Composite

There may be variations in the names
of the
(),
remove
(), and
getChildren
() methods

A
part/leaf
can have no
children; methods like
(),
remove
() don’t make sense for
this class, but are still inherited
from
Component

.

Composite

defines the behavior of
those
Components

having
children and stores the child
Components
.

The Component interface defines
the behavior that both Parts and
Composites must implement

public interface Component {
// behaviors for
Part

and

Composite

public void remove(Component c);

public List<Component>
getChildren
();

public abstract double
getPrice
();
// Part
-
specific

... <other Part behaviors>

}

Q: Should/can Component be defined as an
Interface

rather than an
Abstract Class
?

public class
Composite

implements Component{

private String name;

private double price;

private List<Component> components;

Composite (String name, double
basePrice
) {

//
ctor

details

components = new
ArrayList
<Component>();

}

// essential Composite behaviors:

(c);

}

public void remove (Component c){

components.remove
(c);

}

public List<Component>
getChildren
() {

return components;

}

...public class Composite implements Component{

...continued from previous slide

// context
-
specific behavior

public double
getPrice
() {

double
compositePrice

= price;

for( Component c: components ){

compositePrice

+=

c.getPrice
();

}

return
compositePrice

;

}

}

public class Part implements Component{ // Part is a “Leaf”

private String name;

private double price;

Part(String name, double price) {

this.name = name;

this.price

= price;

}

// Composite
-
related behaviors

// what should we do here??

// do nothing? Throw exception? Return a true/false?

}

public void remove(Component c){

// same as above; what should we do here??

}

public Collection<Component>
getChildComponents
();

// what can we do here??

//

Throw an exception?

//

Return a null?

//

return
Collections.EMPTY_LIST
;

}

}

Consequences

Defines class hierarchy

Leafs(Parts),
C
omposites

Composite may replace
Leaf/Part
in
any client
operation

Simplifies client

No special treatment for
Composites
vs

Parts

every object can
simply be treated as a Component

Clients don’t know (don’t care) whether they are dealing with
Leaf/Part
or
C
omposite.

The specific type of object is
transparent

Easy to add new Component types

No client changes needed

Consequences

Cohesion principle violated!

Two responsibilities in one class

A
Component

defines both
Part
and
Composite

behavior

Also, a
Part
cannot logically support certain behaviors
(
,
remove,
getChildren
)

…or can we just look at a Part as a Composite with no
children???

At any rate, type safety is compromised

Composite Pattern represents a classic tradeoff