A facade is a simple interface to a complex subsystem.
If you have ever written a simple wrapper around the
LeftHandedSmokeShifter subsystem because you only need
four of the 862 options that it offers, then you have
built a facade. I quite like facades and this pattern is used reasonably
often in Ruby: The Pathname class, for example, which is incredibly
useful for dealing with paths and filenames
is mostly a facade.
Why did I leave the Facade pattern out of the book? Well I almost didn’t – but given the space and time restraints of the book that I was trying to write, the facade got left behind because for two reasons: First, I think that facades come so naturally to good engineers that having me go on about them would not have really added very much. Second, there was nothing that interesting to say about Ruby while talking about the facade that I couldn’t say while talking about adapters or proxies or decorators. And so, the facade, the little pattern that could, got left behind…
But if you are really missing your facades, here are some excerpts from an early draft of the book that did contain a chapter on the facade pattern:
The Facade Pattern: The Lost Chapter
Software engineers really have only one enemy. We may whine about customers who cannot make up their minds, we may storm around over the business types cannot see why we need this vital piece of hardware, we can rail about impossible schedules and unreasonable requirements, but none of that is the real problem. No, our one true enemy is complexity. If only we could say the programming things we want to say simply, if only we could squeeze those confusing details out of our code, if only we could iron over those complex technical wrinkles, then our lives, or at least our work would be a lot easier. Because of this, the Facade Pattern is my favorite of all of the original GOF patterns. The Facade Pattern is my favorite because it is all about masking the complexity that plagues us and our code. There really is no magic in the Facade Pattern. The Facade Pattern is simply a formalization of the idea that if you cannot avoid complexity, then the next best thing to do is to isolate it, to keep it from contaminating your whole system. You want to reach for the Facade Pattern when you are just trying to get something done and the tools that you have to do it are complicated.
Using and abusing the Facade Pattern
In the kind architecture that involves building actual buildings, a facade is the front of a structure, the part that you see. So we might have a classical Greek facade, complete with columns and sculptures, covering a modern steel and concrete building. One imagines that building architects try hard to make simple and elegant facades that are not so heavy as to pull down the rest of the structure. Certainly this is true of facades made of bytes. Software facades are a compromise: you are trying to expose just the functionality that you need while holding back the tide of complexity. The key words here are just enough and holding back. You want to expose enough of the underlying system to allow the clients of your facade to get their work done, without reproducing original complex interface in just another form.
Software facades are like their real world namesakes in another way: over time they tend to accumulate crud. Since a well done facade constitutes a pinch point between the client code and the sub-system, it can seem a logical place to add a feature to the sub-system. You say that your printing subsystem doesn’t print collated sets? Well here is the SpoolingSystemFacade, let’s just add the collation code there. Stuck with a database that doesn’t handle rollbacks? Why just stash that extensive and complex rollback logic in the DatabaseFacade.
The trouble with adding features to your subsystem via its facade are many. First, you are muddying up the purpose of your facade: it is suppose to be there to simplify access to the subsystem, not to enhance the thing. Second, if you add features to your facade and then later realize that you need a second facade for the same subsystem, the second facade is not going to have all those nifty new features. If you need to add features to your subsystem, add them to your subsystem – remember, open classes in Ruby means never having to say you are sorry. If you can’t do that, then enhance your subsystem in some other class (perhaps with a decorator?) and build a facade on that.
Facades are meant to be seawalls, holding back the tide of complexity. You can’t do that and add features at the same time.
The facade is yet another of those patterns where an object stands in for one more more other objects. Facades and proxies and adapters and decorators all look something alike. But adapters exist to hide the fact that we are stuck using an object that has the wrong interface. A proxy stands between the user of an object and the object itself and somehow controls access to the object. And decorators add functionality to an object.
The key idea behind a facade is that we are trying to simplify access to the object we are wrapping, the thing behind the curtain. Actually, with a facade the thing we are wrapping is not behind the curtain at all: facades are not meant to hide anything, the way adapters do, but just to make using the thing easier.
Given its purpose, the facade is the antithesis of the decorator: while a decorator tries to add features to an object that does not do enough for us, the facade is trying to dumb down a sub-system that does too much.