Originally I had started out to include the Facade Pattern in the book, but in the end I didn’t. I did however, write a draft of that doomed chapter and here it is.
Software engineers really have only one enemy. We may whine about customers who can’t make up their minds, about impossible schedules or unreasonable requirements, but none of that is the real problem. We are haunted by complexity. It smiles every time we add one more feature to that class, just a bit of
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.