Stories about Software



Quick Information/Overview

Pattern Type Structural
Applicable Language/Framework Agnostic OOP
Pattern Source Gang of Four
Difficulty Easy

Up Front Definitions

The Problem

Let’s say that you work on a web based piece of software that processes orders for customers in some sort of retail capacity and that there is a framework for a lot of existing operations with which you have to deal. You’re tasked with creating the UI for taking orders from customers. At your disposal, you have three handy functionalities: an order DAO for storing order information to the database, a receipt printer for printing receipts, and an email sender for sending confirmation emails. These things exist in different assemblies and your presentation layer assembly, fortunately, has references to all of them.

So, you write some code that looks like this:

Life is good. Your customer can now issue an order through your page and the view model that supports it. Making note of your success, your manager hands you a requirement to display recommendations to the screen following an order. Luckily, there is a module called RecommendationEngine that you can use for just such an occasion:

Excellent. Well, mostly, anyway. This class’s constructor is starting to get a little busy and it depends on sort of a hodgepodge of other assemblies. But, it’s probably nothing — adding that additional assembly reference for the recommendation engine was probably just an anomaly.

Besides, your manager is so impressed that it’s time to assign you to a different screen. As it turns out, there is the traditional order placement screen and a new express one for frequent customers. So, you need to write a new screen and ViewModel, which you do. Since you’ve already implemented the order execution logic, you just copy and paste it and the field declarations into the new ViewModel, initializing the fields in the constructor. You’re not thrilled about the copy and paste, but whatcha gonna do?

At this point, your manager points out a requirement that nobody had considered: users might want to access a virtual copy of their receipts later. You notice an assembly containing a class called ReceiptDao that sounds promising, and you add that:

Well, problem solved, though that dependency list is growing. The order logic now stores the receipt. You promote it and get a defect back from QA that the express ordering system doesn’t store virtual receipts the way the normal one does. Oops. Such is life when you copy and paste program — you forgot to change the other implementation. Ah, well, happens to the best of us.

But now, you get a series of assignments from the manager to add more functionality from other modules while simultaneously adding more places from which an order can be placed. That means adding a lot of code to the two implementations that already exist, bloating them, and then copying and pasting the resulting monstrosity to various other locations.

So, What to Do?

As always in this section, it’s important to identify where things went wrong. It’s debatable as to whether adding that fourth dependency was a problem or not — that constructor is getting pretty busy at this point and the dependency fan out is climbing. However, in and of itself, that may not be a problem.

It stops being debatable (as it always does) when they copying and pasting starts. That’s bad. Any time you find yourself doing that you’re failing at design. In this case, the most obvious fix is the one that will lead us to a better path. Specifically, we need to factor the duplicated code into a class. So, let’s introduce a class called OrderService:

Now, this service class can be used by any ViewModel client without duplicating logic. Here’s what the client now looks like:

The only duplication that might occur here is injecting and invoking the service (though that can be fixed among the ViewModels, but that’s beyond the scope of this post). We’ve eliminated the duplication that makes things like adding the receipt storage a pain point. Also, observe that if we put the service in a separate assembly from the ViewModels, we can now remove the assembly references to the various lower level services such as EmailSender, ReceiptPrinter, etc.

While this separation may seem like pushing our problems out a layer, there is a real benefit to doing this. Specifically, presentation layer classes should not be concerned with locating lower level components. They should be allowed to focus on marshaling data for presentation. Following the single responsibility principle suggests that presenting order confirmation to the user and navigating the mechanics of the subsystems required for an order are two separate responsibilities.

The five (and growing) dependencies that have been added to the constructor of the service to spare the ViewModel are still problematic in terms of good design. This could be fixed with further facades, if the application is large enough to support conceptual sub-layers. That is, there could be a general DAO facade and a general externalities facade that took care of the dao functions and email/receipts/recommendations respectively. This scheme would have the service knowing only about two collaborators instead of five while deepening the call stack hierarchy.

Another approach might be to consolidate some of these assemblies or classes at lower layers, if possible. It might also be reasonable, depending on the situation, simply to leave this service class alone, having abstracted this sub-system out of the presentation layer.

A More Official Explanation

DoFactory defines Facade as a pattern that aims to:

Provide a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use.

This is pretty straightforward to understand and it constitutes one of the most basic and fundamental patterns of programming. Facades provide a layer of abstraction, hiding low level details from client code in favor of broader, easier to understand interactions. I have blogged extensively about the subject of abstraction, if you’d like a more in-depth treatment of the concept.

In general, facades form the back bone of solid architecture in code bases by virtue of hiding conceptually difficult details behind conceptually simple points of access. The crux of this pattern is hiding and managing complexity.

Other Quick Examples

Other incarnations of the Facade Pattern include:

  1. The iconic example of mortgage applications where lenders, banks, inspectors, etc are all necessary to complete the single process.
  2. A unified or single class that you write to hide an ugly third-party API or series of APIs.
  3. In a very real sense, the structure of a class is a bit of a facade since implementation details (private fields and members) are hidden behind the facade of the public API.

A Good Fit – When to Use

Facade is good any time you want to hide details of a process from client code. This can apply, as I mentioned, at the assembly/module level and it can even apply at the class and method level. If you practice good software design this is a pattern that you will find yourself using constantly. It is the essence of providing good abstractions.

Square Peg, Round Hole – When Not to Use

The main usage anti-pattern of a facade is providing a layer or “wrapper” that really does nothing or fails to simplify things for clients. There can be a fine line between organizing code and hiding details and introducing pointless layering, so it is important to consider whether the facade that you’re adding is either (1) making things easier or (2) hiding details that should be hidden. If it’s doing neither of these things, it probably shouldn’t exist.

So What? Why is this Better?

Generally speaking, facades can help eliminate redundant logic and they can simplify interaction with a system. These are two of the most important considerations in all of software. Redundancy is the bane of maintainability and abstraction is the backbone of understandable systems. Well placed facades (such as layered architecture, for instance) provide both in one shot. The end result is that your code will be well factored and decoupled, easy to maintain, and easy to reason about.