During my recent round of interviews for my next consulting gig I was exposed to a barrage of “off the shelf” technical interview questions. Fortunately for you I am not going to bore you with them in this post (though I may choose to regale you with these tales at a later time). A fair number of the questions that I was asked glanced off of and dodged around the topic of design patterns. In one such interview the Adapter Pattern came to the forefront of the conversation. I say “conversation” because I prefer to conduct and participate in interviews using a conversational style rather than the oft used interrogation style, a series of rapid fire questions given as the interviewer checks off the answers on his answer sheet. As I completed my eloquent explanation of the pattern one interviewer asked me, “What is the difference between the Adapter and the Facade pattern? They seem like they are doing the same thing to me.”
This question really caught me off guard because until that moment I had not given it much thought. In my mind they are distinct patterns that solve different problems. It is never good in an interview to appear that you have been caught off guard so I mustered a meek answer. After further thought and consideration I have developed a much stronger response to the interviewer’s question.
In this post I will clearly demonstrate the differences between these two patterns by crystallizing their intent and demonstrating when it would be appropriate to use each pattern.
Scenario 1: The Adapter Pattern
Assume that we are faced with the following situation. We have an existing class in our system called “A”. We have decided that we need to change the “B” class to use the “A” class rather than the “C” class it is currently using. However, “B” is dependent on the “C” interface which is different from the one exposed by “A”. How do we make this work?
The Adapter Pattern is intended to help us solve just this problem by creating a class that “adapts” the exposed interface of a class to an interface that is expected by the new client. To use this pattern to solve the problem described earlier we create a third class called “A2C” that has the “C” interface that the “B” class is expecting. Inside our “A2C” class is the necessary logic to wire the “B” class to the “A” class without either of the existing classes having to change in any material way. Now we just change “B” to depend on “A2C” rather than depending on “C”. If we were smart enough to inject this dependency into “B” then “B” won’t have to change at all. This keeps us from having to change “A” and in doing so makes it impossible for us to break “A” and any of its other clients.
Scenario 2: The Facade Pattern
For scenario 2 assume that we are dealing with the following circumstances. We need to integrate our new application with an existing legacy subsystem. This subsystem has a relatively complex API that consists of a number of class each with a number of public methods. To integrate our new application with this subsystem we need to instantiate only some of the classes and then use these objects via a few of the methods calls on each object. How should we integrate with this subsystem?
Keep in mind that we are integrating with a subsystem here. So it’s possible that one day this entire subsystem could be replaced. If we integrate directly with each class and method directly then we have created a tight coupling between our new application and the subsystem and if the underlying subsystem did change then we would have to go into our new application and do some “shotgun surgery” to fix all of our dependencies. A better solution is to create an abstraction layer that would insulate us from future changes in the subsystem and simplify the API, all at the same time? The Facade Pattern has the recipe to help us create this abstraction layer. I can always remember the Facade Pattern because I think of Facade in the construction/building/architecture sense. In these terms, a Facade is a thin decorative front that is used to hide something ugly underneath it. The Facade design pattern has a similar definition, in that it is used to make an complex API simpler and (hopefully) prettier to the client.
So we have decided to implement the Facade pattern. We do this by creating our Facade class. This class exposes a minimal set of public methods that our new system will use in lieu of communicating directly with the subsystem. The Facade class will handle the object creation for any classes in the subsystem that are needed. Now if the underlying subsystem ever changes or is replaced the impact to our new system will be limited to the Facade class that we have created.
What We Have Learned
The Adapter Pattern and the Facade Pattern solve different problems. As we have seen each pattern has a different intent and a different implementation. The intent of the Adapter Pattern is to adapt one classes interface into an expected interface used by an existing client class or classes. The intent of the Facade Pattern is to simplify the API of a subsystem.
So to answer that interviewer’s question again, “No! These patterns are not doing the same thing. They are intended to do very different things and solve very different problems.”