Simplified Facade (Structural Pattern)
🌑 Why Facade Pattern
After successfully releasing the movie review application, Architect Spidey wanted to analyze how many users start and do not complete a movie review. She needs to integrate a third-party analytic framework within the application. She was interested in the Google Analytics library. Implementing analytics event logging in an application requires interaction with multiple Firebase library objects, such as FirebaseApp, Analytics, etc.
She needs a simple interface for her application that hides the complexity of interacting with the internal objects of Analytics and provides a single point of access.
Like Architect Spidey has a single point of contact for all the gossip in the neighbourhood, i.e. her mom. Her mother caught all the gossip from the different spiders in the neighbourhood.
🌥️ Outline
The Facade pattern is a structural pattern that provides a simple interface to a complex library. It hides the complexity of interactions between different objects in the library.
Facade - Face of a building.
🌜Facade In Real World
A desktop computer on your table is a good example of a facade pattern. You need to press the power button, and everything is behind-the-scenes. The power supply sends electricity to all components and initialises the BIOS, Load instructions from ROM, etc.
All these complex tasks happen secretly, and the person sitting in front has a single interface a Power button :).
🌕 Solution
Architect Spidey created a class EventTracker to track the events with in the application. SShe declares the methods setupTracker and trackEvent(event) to handle event tracking.
With this approach, Architect Spidey decouples the application code from the third-party framework. It also simplifies code when using limited functionality from the vast library. All objects in the application interact with EventTracker and further EventTracker interacts with the subcomponents of the Analytics library of Firebase.
Facade Components
Facade Class:
The simplified interface of a library that is responsible for delegating client requests to appropriate subsystem objects of the library. It comprehensively understands the library’s objects, including their properties, methods, and relationships.
Library:
It is a complex system for which a facade is required. An application needs this system to achieve a specific functionality. Further, this system has multiple subsystems(objects), and to avoid directly using these objects within the client code a facade component is created.
🌟 Where To Apply
Use the Facade to provide a simple interface to a complex library
A complex library might have multiple subsystems, and your application needs to interact with these subsystems. Directly using these subsystem objects in application code will create direct dependency on the library. Facade helps to remove dependency on the library. When Architect Spidey added the Google Analytics framework to her movie review application. The application does not need to know the framework & its subsystems like Analytics, FirebaseAuth, etc. It requires to call a method of Facade class and the rest is done by it. With this approach, the application depends upon the facade interface rather than the Google Analytics library.
Use the Facade to provide limited functionality from a vast library
Use a facade pattern when using limited functionality from a library. Architect Spidey wants to integrate a media framework to display movie trailers. The media framework provides large functionality like audio settings, frame settings, video cropping, etc. She just needs to play a video with minimal control which can be achieved simply by adding a facade class for the application.
🌓 To Gain Something, You Must Trade Off
Design patterns are solutions to common problems in software design. They provide a structured approach to solving issues, much like a blueprint. While it’s possible to solve a problem without using a design pattern, applying one offers better flexibility, scalability, and maintainability. However, each benefit comes with its trade-off. Let’s examine this concept in the context of the Facade pattern.
Decoupling vs Limited flexibility
The facade class decouples the application code from the library, so instead of the library interface, the application depends upon the facade interface. To play a video in the movie review application, it simply needs to call a method on the Facade class, and the class handles the rest. In the future, if anything is changed in the library, it does not directly impact the application.
Sometimes, the facade interface may be too rigid for certain clients, and clients may have limited control over the functionalities of the subsystem. Suppose a movie review application needs to display a screenshot from the video on a movie detail screen. The function to capture a screenshot from a video exists in the library; however, it was not exposed through Facade.
Reusability vs God Object
Sometimes, a couple of objects in an application require access to a library and, with the help of facade boilerplate code to access the library, are moved in the Facade class. For the movie review application, almost all objects require access to Analytics and EventTracker class is responsible for all setups for the library.
On the other hand, a Facade can become a God Object—an object that is overly dependent on or entangled with many other classes in the application.
Readability vs Performance overhead
The facade provides a single, easy-to-use interface that hides the subsystem’s complexity, improving the readability and usability of the client code. On the other hand, it adds an extra layer of abstraction and communication between the clients and the subsystems, increasing latency and resource consumption and affecting the system’s speed and efficiency.
🌚 Some Interesting Fact
Facade & Adapter Pattern
The facade provides a new interface to interact with a complex framework. However, the adapter fits the new object in the existing interface. The Adapter pattern typically adapts a single object to match an expected interface, whereas the Facade interacts with and simplifies access to multiple objects.
Facade & Mediator Pattern
The Mediator pattern is used to control communication between multiple objects (colleagues) by introducing a central mediator object. This helps reduce the direct dependencies between the objects, promoting loose coupling. All the communication logic is managed by the mediator, and sub-components are aware of and communicate through this mediator.
However, the facade class provides access (simple interface) to sub-components of a large component.
Code Example (Swift)
Facade Interface & Class:
1
2
3
4
protocol EventTracker {
func setupTracker()
func logEvent(event: Event)
}
1
2
3
4
5
6
7
8
9
10
11
class DefaultEventTracker: EventTracker {
func setupTracker() {
//FirebaseApp.configure()
//Analytics.setAnalyticsCollectionEnabled(true)
//Auth.auth().signInAnonymously
}
func logEvent(event: Event) {
//Analytics.logEvent(event.type, parameters: event.detail)
}
}
An Event Struct to support
1
2
3
4
5
struct Event {
let type: String
let timestamp: Double
let detail: [String: String]
}
Comments powered by Disqus.