user310291
user310291

Reputation: 38238

Difference between the Facade, Proxy, Adapter and Decorator design patterns?

What is the difference between the Facade, Proxy, Adapter, and Decorator design patterns?

From a generic point of view, such patterns seem to do the same thing, that is: wrap an API and provide access to it.

How to distinguish these patterns?
How to discern when one pattern suits more than the others?

Upvotes: 185

Views: 90243

Answers (2)

dirkgently
dirkgently

Reputation: 111336

TL;DR

  • Adapter: for non-compatible interfaces
  • Facade: for making interfaces simpler
  • Proxy: for managing a heavy and/or complex object
  • Decorator: for extending it at runtime

Detailed

Adapter adapts a given class/object to a new interface. In the case of the former, multiple inheritance is typically employed. In the latter case, the object is wrapped by a conforming adapter object and passed around.

Facade is a simple gateway to a complicated set of functionality. You make a black-box for your clients to worry less.

Proxy provides the same interface as the proxied-for class and typically does some housekeeping stuff on its own. So, instead of making multiple copies of a heavy object X you make copies of a lightweight proxy P which in turn manages X and translates your calls as required.

Decorator is used to add more gunpowder to your objects (note the term objects — you typically decorate objects dynamically at runtime). You do not hide/impair the existing interfaces of the object but.

Now that you have decorator involved, you will probably want to know why the emphasis on the word object — some languages (like Java) simply don't allow virtual inheritance (i.e. multiple inheritance as C++ does) to allow you to accomplish this at compile time.

Since we have dragged in multiple inheritances (and the dreaded diamond) you will look out for mixins — which are ordered linear chaining of interfaces to get around the problems of multiple inheritance. However, mixins don't mix that well. And we end up with traits — yes those stateless little blobs of behavior that you see pop-up all the time in template parameters in C++. Traits try to address the issues of composition and decomposition of behavior in an elegant manner while not going either for multiple inheritances or ordered chaining.

Upvotes: 352

Jason Evans
Jason Evans

Reputation: 29186

Facade

You could use a facade, for example, to make calls to an API easier. Take a look at this example of a remote facade. The idea here is that the full implementation of the code on the server is hidden away from the client. The client calls 1 API method which, in turn, can make 1 or more API calls on the server.

Adapter

A good example of this can be found here, on Wikipedia. A client object Source would like to call a method on another object Target, but that other object's interface differs to what the client is expecting.

Enter the adapter object.

It can take a call from the Source object and, behind the scenes, call the Target method which should be used.

Source->CallMethodAOnTarget() ---< Adaptor.CallMethodAOnTarget() this calls ---> Target.MethodWithDifferentSignatureAndName(int i)

As for Proxy, I don't have any experience of this design pattern.

Upvotes: 19

Related Questions