Java Reference
In-Depth Information
Composite
Pattern Properties
Type: Structural, Object
Level: Component
Purpose
To develop a flexible way to create hierarchical tree structures of arbitrary complexity, while enabling every
element in the structure to operate with a uniform interface.
Introduction
You've decided to enhance the Personal Information Manager to let users manage a complex project. Features of
this enhancement include defining the project as a group of tasks and related subtasks, and associating
deliverables with tasks. A natural way to accomplish this from a programming perspective is to define a tree
structure, where the root task (which represents the project itself) branches out to subprojects, subsubprojects, and
so on. Therefore, you define a Task class that holds a collection of other Task and Deliverable objects. Since
both the Task and Deliverable relate to the project, you define a common parent for them—the ProjectItem
class.
However, what happens if users need to perform an action that depends on the whole tree? For example, a project
manager wants a time estimate for tasks and deliverables for one project. To accommodate this, you write code to
traverse the tree and call the appropriate methods at each branch. That's a lot of work, however, involving
separate code to walk the tree, call the methods, and collect the results. And with different classes ( Task and
Deliverable ) at each branch of the tree, you might need to handle them differently when getting time estimates.
For a large number of classes or a complex tree, the code quickly becomes difficult to manage.
There's a better way to solve this problem. With the Composite pattern, you can use polymorphism and recursion
to provide an efficient, simple, easy-to-maintain solution.
Begin by defining a standard method for all classes that provides the time estimate, called getTimeRequired .
Define this method for the ProjectItem interface, and implement that behavior in all classes that are types of
ProjectItem . For Deliverable , define getTimeRequired to return 0, because a deliverable does not have time
associated directly with it. For the Task class, return a time consisting of the time for the task plus the sum of the
getTimeRequired calls for all of the Task children.
Using this pattern, you define getTimeRequired so that it automatically calculates the project time estimates for
any part of the tree. Just call the getTimeRequired method for the part of the Task needed, and the code in the
method takes care of the job of traversing the tree and calculating results.
Applicability
Use the Composite pattern when:
There is a component model with a branch-leaf structure (whole-part or container-contained).
The structure can have any level of complexity, and is dynamic.
You want to treat the component structure uniformly, using common operations throughout the hierarchy.
Description
Object-oriented developers are often interested in developing components that follow a whole-part model.
Whole-part model is a model that allows you to treat a collection of identical objects (the parts) as one entity (the
whole). Typically, these structures should be flexible and easy to use. Users should be able to modify the
structure as an application runs, adding or removing parts to suit their needs. At the same time, it's desirable to
keep the complexity of the structure hidden behind the scenes, so that users perceive only a seamless, unified
product.
 
Search WWH ::




Custom Search