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

Decorator

Also known as Wrapper

Pattern Properties

Type: Structural, Object

Level: Component

Purpose

To provide a way to flexibly add or remove component functionality without changing its external appearance or function.

Introduction

The Composite pattern example in the previous section added project functionality to the Personal Information Manager, with a Project composed of a hierarchy of Task and Deliverable objects. All classes implemented the ProjectItem interface, which identified them as classes that belonged to a project.

What if you wanted to extend the basic capabilities of the Task and Deliverable classes, adding extra features like the following?

Dependent items – A ProjectItem that depends on another Task or Deliverable for completion.

Supporting documents – A Task or Deliverable that can reference additional reference documentation.

If you added these capabilities by subclassing, you would have to code a lot of classes. For instance, to make only Deliverable support these features, you would have to write four classes: Deliverable,

DependentDeliverable, SupportedDeliverable, and SupportedDependentDeliverable.

Faced with this drawback, you might consider object composition as a way to add the new functionality. Coding optional support into Deliverable and Task for both new features, however, can mean maintaining duplicate code in multiple locations. At the very least, you increase the amount and complexity of the code.

What if, instead, you produce classes that have “plugin” capabilities? Instead of trying to add features to Task and Deliverable

directly, you create dependent classes that can be attached to any ProjectItem to extend the basic functionality. You could say it's the coding equivalent of adding a 3D sound set to your standard stereo. Your basic audio capabilities remain the same, only now you have some extra feature to play with. For example, define a DependentProjectItem and a SupportedProjectItem. Each class has only the code needed to support its optional capability, and a reference to the real ProjectItem that it extends. This means you have less code to maintain, and the freedom to use any combination of these Decorator classes to add groups of capabilities to

ProjectItems.

Applicability

Use the Decorator pattern when:

You want to make dynamic changes that are transparent to users, without the restrictions of subclassing.

Component capabilities can be added or withdrawn as the system runs.

There are a number of independently varying features that you should apply dynamically, and which you can use in any combination on a component.

Description

Some objects have complex functionality and/or structure that can be added or removed in an accurate component model. In the same way that overlays can be added to a map, showing additional features such as cities or elevation, you might want the flexibility to add and remove certain features for an object.

114