views:

186

answers:

3

The Decorator Pattern is dynamic extension-at-runtime of classes. It dynamically forms a is-a relationship.

I started to wonder if I was over-complicating my API by using the Decorator Pattern after I got this answer about the difference between a mixin and an abstract class.

+1  A: 

I'm not sure I agree with the statement that Decorator extends at runtime. I know that's what Wikipedia says, but I don't think it's accurate. I'd suggest reading the GoF's definition of the Decorator pattern. It is a dynamic extension, yes, but it certainly doesn't have to be at runtime.

Marc W
It doesn't have to be, but it can be.
leeand00
+2  A: 

When using the decorator pattern, you generally are encapsulating, rather than extending (or mixing in) the base class. Often you do this because you want to use the functionality of the class but you want to wrap the calls to it so you can do some extra steps before or after the call. Consider a LoggerDecorator

public class LoggerDecorator implements SomeInterface {
      private SomeInterface delegate;
      public void someMethod() {
          LOGGER.debug("someMethod called");
          delegate.someMethod();
      }
}

You don't want to actually expose the delegate but you want to use its functionality. So whether or not you us mixins, extends a class, or decorate really depends on what you're trying to do. Are you extending a class and adding new functionality to it? Or are you wrapping/decorating the class?

Jeff Storey
@Jeff Please see what I have commented on in Gishu's post below and tell me if I've got it or not.
leeand00
I think you're on the right track, but AOP is a dynamic interceptor framework, which occurs at runtime (or compile time if you compile with aspectj). Generally I'd recommend going the decorator route unless you need AOP because the runtime injection can be a lot more brittle if you're not careful.
Jeff Storey
+2  A: 

A mixin is apt when you're adding some behavior to your class. e.g. the ability to enumerate in case of a collection type. You can mixin as many sets of behavior into your class as you want. Its a nice way to reuse common code ; you basically get a bunch of methods for free.

A decorator on the other hand is more of a sneaky interceptor. It exposes the same public interface as the target object, contains a target object to which it delegates all client calls ; however it decorates the call with some pre and/or post processing. e.g. if I'm writing code against a MyCollection and I want all calls to this type to be logged. I could derive a new decorator MyCollectionWithTimeStampedLogging both deriving from an ICollection base so that they look identical to the client. The decorator would take an instance of ICollection as a ctor param and delegate calls to it. e.g. Add would look like this

public void Add( int item)
{
  _logger.log(String.Format( "{0} Add called with param {1}", DateTime.Now, item.ToString());
  _collection.Add(item);
  _logger.log(String.Format( "{0} Add completed with param {1}", DateTime.Now, item.ToString());
}
Gishu
So a decorator is a little closer to what Aspect Oriented Programming (AOP) does, and a mixin just modifies your existing classes?
leeand00
@leeand00 - kind of; AOP is a lot more than just decorators I think. Mixins are more prevalent in dynamic languages, with a mixin, you 'mix in' a bunch of methods into your class definition. e.g. you can write Load and Save implementations (which reflect on a class and read/write public properties to disk) in a Module Persistable, then mix in this into multiple classes. All of these classes can now be persisted to disk.
Gishu
@Gishu With AOP (which I'm more familiar with than...say mixins) you can specify 3 different things that can happen with the selected interfaces, You can specify a pre-action, a post-action, and an instead-of action.
leeand00