Choose the category of application you would like to embed from the list on the left.
Table of ContentsThe Façade PatternContextual ForcesMotivationProvide a simplified, improved, or more object-oriented interface to a sub-system that is overly complex (or may simply be more complex than is needed for the current use), poory designed, a decayed legacy system, or otherwise inappropriate for the system consuming it. Façade allows for the re-use of a valuable sub-system without coupling to the specifics of its nature.EncapsulationThe sub-system’s nature (complexity, design, decay, OO/Procedural nature, etc...).Optionally, the presence of the sub-system itself (see Questions, Concerns, Credibility checks) Procedural AnalogWhen creating large procedural systems, often we will create a "gateway routine" as a sort of API that allows the aggregation of many different parts of the system into a single called routine. This "gateway" routine makes the system easier to use, and is essentially the precursor to a Façade in an object-oriented system. It it not strictly an analog, it is in fact an early version of the pattern.Non-Software AnalogA hotel concierge (at an upscale hotel) stands between the hotel guest and all the various services that are needed to make for a successful, satisfying stay at the hotel.The guest has goals, which are expressed from the guest's point of view. The concierge translates these goals into needed interactions with the concrete services needed to achieve them. For example, the guest may say "we'd like to go out to an evening dinner, and a show, and they return to the hotel for an intimate dessert in our room". The concierge handles all the nitty-gritty details (a taxi, restaurant reservations, theatre tickets, housekeeping prep of the room, the kitchen preparing the dessert, room-service delivery, etc...) ![]() The concierge here is the Façade analog. Implementation ForcesExample![]() public class Façade {
public void m1() {
// make all calls into the existing system,
// hiding the complexity
}
public string m2() {
// make all calls into the existing system,
// converting the return
return rval;
}
}
Questions, concerns, credibility checksCan we totally encapsulate the sub-system? The Façade can be a convenience service or a constraining service. Convenience: The System Under Development can "go around" and use the existing sub-system directly for infrequent, unusual, or orthogonal needs. This keeps the interface of the Façade relatively small and cohesive, but couples the System Under Development to the sub-system. The call marked "optional" in the diagram above shows this behavior. Constraining: The System Under Development must use the Façade for all accesses to the existing sub-system. This may broaden the interface of the Façade, and weaken its cohesion, but it makes the sub-system itself completely swappable. Because the sub-system is hereby encapsulated, we often refer to such a Façade as an “Encapsulating Façade”. Can we make the Façade stateless? Façades are often fairly heavyweight and instantiating them can impact performance. Therefore, if they can be made stateless, they can be implemented as Singletons, which alleviates the performance and resounce impact of the Façade. Options in implementationFaçade is often implemented using other patterns. In fact, the Façade is not really a specific design, but rather a role that is implemented in whatever way is considered most appropriate given the forces in the problem. For example, here is a Façade implemented using a Chain of Responsibility ![]() To keep a Façade stateless, often it is advisable to externalize the state into a lightweight object: ![]() Legacy Conversion: Façades also can have a strong role in converting legacy systems incrementally to more modern software. The following example is one drawn from the work of Martin Fowler, and I came across it while reading Brian Marick's work on testing, reflected in his blog "Exploration Through Example" (http://www.testing.com/cgi-bin/blog/2005/05/11) "Strangling" a Legacy System Imagine an old, very decayed, and poorly-implemented legacy system. You've probably had to work with one or more of these in your practice. We often think of them as a "big ball of mud" because they are incomprehensible, brittle, and "dense": Job one is to stop using the system in the old way when writing new code that has to interact with it. If we could, we'd stop here and refactor or rewrite the system entirely, but often that is simply not an option: we have to live with it, at least for now. However, using the old system directly (as the "legacy users" do) will mean writing code that is similar in nature to the code in the system, and at the very least we want our new code to be clean, tested, and object-oriented. So, we create a Façade with the interface we "wish we had" and then delegate from there into the various routines in the legacy system. Now that we have this in place, the "new users" can be developed more cleanly and with higher quality. Now, over time, and without siginifcant time pressure on the project, we can incrementally pull out behaviors from the legacy system into more clean, tested, object-oriented code, and delegate from the old routines into the new ones: Once we reach the point that the legacy system remains only as a series of delegation points, nothing but a thin shell around the new behaviors, we can begin to refactor the legacy users to use the Façade instead of the delegating routines in the older system. The Façade itself can also be refactored to use the new code directly. Again, this can be done incrementally, as time permits, without a lot of pressure. Naturally, once all the legacy users and the Façade no longer use the thin-shell legacy system, it can be retired. Consequent ForcesTesting issuesFaçades are inherently difficult to test if (as is common) the sub-systems they cover are hard to test. However, the presense of the Façade makes the System Under Development fundamentally easier to test because the Façade, once in place, can be Mocked to eliminate unpredictable dependencies.![]() Cost-Benefit (gain-loss)A Façade keeps the client system clean, reduces complexity when accessing existing sub-systems, and can allow for the re-use of valuable legacy systems in a new context, without reproducing their problems.An Encapsulating Façade de-couples the client system entirely from the sub-system, which means the sub-systems can be swapped, eliminated, crippled, etc... This allows for easy creation of
Imagine we are working on an application with a 3-tiered architecture (UI, Middle, Data), and we want to work in a test-driven way. Unfortunately, our teams are all blocked: Our teams are blocked:
We can use Façades to separate these layers. The Façades will present the interface of the consuming layer, and later can be coded to the implementation of the service layer in each case, when this becomes available (it can be stubbed out, initially). Also, each Façade will be a mockable entity, and so the layers can be test-driven: Note that the content you create on http://www.netobjectivesrepository.com is licensed under the Creative Commons Attribution 2.5 License. Please only submit content that you write yourself or that is in the public domain. Learn more about our open content policy. |
|||