Wednesday, March 2, 2011

Decorator vs Adapter pattern


The purpose of the adapter pattern (aka wrapper) is to convert (or present) the interface of an existing class, into an interface that is compatible with an otherwise incompatible client class. In an adapter class, you are actually changing the interface that is being presented (not the actual class's public methods, but by wrapping the class in another class). No new functionality is created in an adapter class, it merely does as its name implies, makes two things that weren't designed to fit together - fit together.

A decorator class does not change the interface of the original class, but may extend it with additional functionality. The decorator pattern allows for the functionality of the original class to be modified at runtime without subclassing. A decorator is slightly confusing to explain but: it is a subclass of a component class, that takes a concrete instance of the component class in it's constructor, and will will either proxy method calls to the concrete instance that was passed in, or provide it's own implementation.

  Adapter / Wrapper Decorator
Composes "origin" class True True
Modifies original interface True False
Modifies behavior of interface
False True
Proxies method calls True True

The adapter class will proxy calls from the interface to the client to the interface of the original class that is being wrapped. The adapter class may perform translation upon the inputs of the client class that are being passed to the original class, and upon the output from the original class that are being returned to the client class.

Often, the use of an adapter, or wrapper, pattern is to bridge new code with legacy code, especially when the legacy code cannot be modified. For instance, a library, or software package that exists in a system that cannot be updated, but needs to be communicated with is a good candidate to be wrapped.

UML Abstraction of Adapter / Wrapper Pattern

UML Abstraction of Decorator Pattern
UML of decorator pattern


Legacy class Importer writes data to a database. The legacy class Importer has a method called, import() that takes a string in CSV format. Unfortunately, we have a new tool called SlickExporter. It exports data only in JSON. To make these two classes talk to eachother, we provide a wrapper, aka adapter, class around Importer called ImporterWrapper that now accepts JSON, and translates it to the CSV format that the Importer requires.

No comments:

Post a Comment