Facade is a structural design pattern that provides a simplified interface to a library, a framework, or any other complex set of classes. A facade might provide limited functionality in comparisn to working with the subsystem directly. However, it includes only those features that clients really care about.
Note: clients
in design patterns refers to the lines of code in our application that is using/calling or consuming other set of code.
Instead of making your code work with dozens of the framework classes directly, you create a facade class which encapsulats that functionality and hides it from the rest of the code. This structure also help's you minimize the effort of upgrading to future versions of the framework or replacing it with another one. The only thing you'd need to change in your app would be the implementation of the facade's methods.
Imagine that you have a script where for each DOM element found on a page with class "foo", we wish to increment a counter. What's the most efficient way to query this collection of elements? Well, there are a few different ways this probelem could be tackeled:
querySelectorAll()
to select all of the elements with the class "foo".getElementsByClassName()
to similarly get back the desired collection.So, which of these options is the fastest? It's actually option 3, by a factor of 8 - 10 times the alternatives. But we have a probem, option 3, doesnot work with some legacy browsers and we need to support them.
To simplify query selection, jQuery creates a Facade, which, behind the scenes will opt for the most optimal approach to selecting elements depending on what our current browser supports and we can just consume the abstraction layer.
We're probably all also familiar with jQuery's $("selector")
. This is significantly more easy to use for selecting HTML elements on a page versus having to manually opt for getElementById()
, getElementsByClassName()
, getElementsByTagName()
and so on.
Behind the scenes, the library simply opt for the most optimal approach to selecting elements depending on what the users current browser supports and the client code just consumes the abstraction layer.
Using Facade to simplify an interface for listening to events corss-browser. We do this breating a common method that can be used in one's code which does the task of checking for the existence of features so that it can provide a save and cross-browser compatible solution.
// Facade
var addMyEvent = function (el, ev, fn) {
if (el.addEventListener) {
el.addEventListener(ev, fn, false);
} else if (el.attachEvent) {
el.attachEvent("on" + ev, fn);
} else {
el["on" + ev] = fn;
}
};
Client or the Consumer of the Facade dont need to worry about the cross browser checkings.
// Client
addMyEvent(document.getElementById("facade-pattern"), "click", () => { console.log("Heading clicked.") });
So, We use facade pattern to provide a simple interface to a complex sysmtem.