Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Applied Java™ Patterns - Stephen Stelting, Olav Maassen.pdf
Скачиваний:
202
Добавлен:
24.05.2014
Размер:
2.84 Mб
Скачать

A general consideration when implementing this pattern is whether each component should have a reference to its container (composite). The benefit of such a reference is that it eases the traversal of the tree, but it also decreases your flexibility.

Benefits and Drawbacks

The Composite pattern provides a powerful combination: considerable flexibility of structure and an extremely manageable interface.

The structure can be changed at any time by calling the appropriate methods on a Composite to add or remove Components. Changing a Composite’s Components means you're able to change the behavior of the Composites.

No matter where you are in the tree structure, you can call the same method on each of the individual components.

The use of interfaces further increases the flexibility. Interfaces allow the construction of frameworks using the Composite pattern and they enable the introduction of new types at runtime.

At the same time, use of interfaces can be a drawback when you want to define attributes and provide default implementations in order to let each of the nodes inherit behavior. In that case, the Component needs to be an abstract class.

Another drawback of the pattern arises from its flexibility—because it is so dynamic, the Composite pattern is often difficult to test and debug. It normally requires a more sophisticated test/validation strategy that is designed around the concept of the whole-part object hierarchy. If testing becomes a problem, the best approach is to build the testing into the Composite class implementation.

Additionally, the Composite normally requires full advance knowledge of the structure being modeled (in other words, a full class design for the Composite), or a more sophisticated class-loading mechanism. The interface form of this pattern (discussed in the Pattern Variants section) can be a useful alternative for providing dynamic behavior during runtime.

Pattern Variants

Some variations on the base Composite pattern include:

The root node – To improve manageability in systems, some Composite implementers define a distinct object that acts as the base for the entire Composite object hierarchy. If the root object is represented as a separate class, it can be implemented as a Singleton, or the access to the root node can be granted through a Singleton, without the class itself being a Singleton.

Rule-based branching – For more complex Composite structures, typically those with multiple types of nodes and branches, you might need to enforce rules about how and when certain kinds of nodes can be joined to certain branch types.

Related Patterns

Related patterns include the following:

Chain of Responsibility (page 42) – Used with the Composite pattern when methods need to be propagated “up” the tree, from leaves to branch nodes.

Flyweight (page 183) – When the tree structure becomes large, applying the Flyweight pattern can help reduce the number of objects managed by the tree.

Iterator (page 69) – The Iterator pattern can be used with the Composite pattern to encapsulate the traversal of the tree, which otherwise could become complicated. Iterator is sometimes used to traverse a Composite.

Visitor (page 121) – Used with Composite to centralize behavior that would otherwise have to be split among the leaf and branch classes.

Composite View [CJ2EEP] – The Composite View pattern describes how a view can be composed of several other views (which in turn can be composed of views), similar to the Composite pattern.

110