Design Patterns – How to Add Functionality to an Existing Object

adapterdesign-patternsobject-oriented

I have an interface that has a certain amount of well-defined functionality. Let's say:

interface BakeryInterface {
  public function createCookies();
  public function createIceCream();
}

This works well for most implementations of the interface, but in a few instances, I need to add some new functionality (like perhaps rolled into a new method, createBrownies()). The obvious/naive approach to doing this would be to extend the interface:

interface BrownieBakeryInterface extends BakeryInterface {
  public function createBrownies();
}

But has a pretty big downside in that I can't add the new functionality without modifying the existing API (like changing the class to use the new interface).

I was thinking about using an adapter to add the functionality after instantiation:

class BrownieAdapter {
  private brownieBakery;

  public function construct(BakeryInterface bakery) {
    this->brownieBakery = bakery;
  }

  public function createBrownies() {
    /* ... */
  }
}

Which would net me something like:

bakery = new Bakery();
bakery = new BrownieBakery(bakery);
bakery->createBrownies();

This seems like a good solution to the problem, but I'm wondering if I'm awakening the old gods by doing it. Is the adapter the way to go? Is there a better pattern to follow? Or should I really just be biting the bullet and just extending the original interface?

Best Answer

Any of the Handle Body patterns could fit the description, depending on your exact requirements, language, and needed level of abstraction.

The purist approach would be the Decorator pattern, which does exactly what you are looking for, dynamically add responsibilities to objects. If you are actually building bakeries, it's definitely overkill and you should just go with Adapter.

Related Topic