Flutter Design Patterns: 7 — Facade

An overview of the Facade design pattern and its implementation in Dart and Flutter

Mangirdas Kazlauskas
Nov 28 · 7 min read

In the last article, I have analysed one of the behavioural design patterns — State. This time, I would like to represent a pattern which you have probably already used as a developer, but just did not realise that it is a design pattern at all. Therefore, let me introduce you to Facade.


Table of Contents

  • What is the Facade design pattern?

What is the Facade design pattern?

Dealing with Complexity (source)

The Facade belongs to the category of structural design patterns. Its intention in the GoF book is described as:

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

The Facade pattern is very straightforward — it allows you to create a simplified class which wraps the set of methods/operations of the complex API or subsystem. Clients only communicate with the subsystem through this facade class which forwards all of the requests to the appropriate subsystem objects. As a result, the number of dependencies and references between client and subsystems is reduced (the weak coupling is promoted between them), the facade provides a simple interface of the subsystem that is good enough for most clients.

And that is pretty much it. Really, it is that simple! Of course, more information is provided in the analysis and implementation sections, so let’s dive deeper into the details.


Analysis

The general structure of the Facade design pattern looks like this:

Structure of the Facade design pattern (source)
  • Facade — knows which subsystem classes are responsible for a request and delegates the request to subsystem objects. The facade provides methods to access a particular part of the subsystem’s functionality;

Applicability

There are two main use cases of the Facade design pattern:

  1. When you want to provide a simple interface to a complex system. Usually, subsystems get more complex as they evolve and becomes harder to use for clients. Hence, the first part of this use case is to provide a simplified class of the most-used features of the subsystem which fit most client requirements. The second part is that the Facade design pattern allows you to reduce the coupling between multiple subsystems by requiring them to communicate only through facades.

Implementation

Let’s say you want to fulfil your dream of having a smart house. You have bought a lot of smart devices from different providers and connected them to your network, but there is a problem — every device provides its interface (call it an API) so it becomes very tedious to manage different devices separately to accomplish a single task.

For instance, you want to watch a movie just like in the cinema. For this, you have to set up your house environment in a similar way:

  • Turn off the lights;

For all of these steps, you have to call several APIs just to set-up your environment. Wouldn’t it be nice just to say “Start playing The Matrix in home cinema mode” to your smart home assistant or turn on a single switch in your smart home mobile application and execute all of these steps as a single action? To implement this kind of functionality, the Facade design pattern is a great option!

Class diagram

The class diagram below shows the implementation of the Facade design pattern:

Class Diagram — Implementation of the Facade design pattern

There are several APIs provided to communicate with smart devices (turn them on and off): AudioApi, CameraApi, PlaystationApi, SmartHomeApi and TvApi. NetflixApi provides methods to connect to the Netflix platform, disconnect from it and play the selected movie.

APIs are used by the facade classes:

  • GamingFacade — uses the PlaystationApi and CameraApi and provides methods related to gaming and streaming actions;

Both of the facades use the SmartHomeState class to save the current state of smart devices.

FacadeExample widget contains the SmartHomeFacade to communicate with the smart devices using the provided action methods in the facade.

APIs

AudioApi — an API to turn the smart speakers ON/OFF.

CameraApi — an API to turn the streaming camera ON/OFF.

NetflixApi — an API to connect to the Netflix platform, disconnect from it and play the movie.

PlaystationApi — an API to turn the gaming console (PlayStation) ON/OFF.

SmartHomeApi — an API to turn the smart lights ON/OFF.

TvApi — an API to turn the smart TV ON/OFF.

Kittens break

If you have read to this point, you definitely deserved this!

SmartHomeState

A class which holds the current state of all the smart devices at home.

GamingFacade

A facade class which uses APIs of the PlayStation and streaming camera and provides simplified methods to use them:

  • startGaming() — uses the PlaystationApi to turn the gaming console on;

SmartHomeFacade

A facade class which uses APIs of the smart TV, audio devices, Netflix platform and smart home equipment. Also, GamingFacade is used. Several methods are provided to simplify smart home actions:

  • startMovie() — uses several different APIs to turn off the lights, turn on the smart TV and speakers, connect to the Netflix platform and start playing the selected movie;

Example

First of all, a markdown file is prepared and provided as a pattern’s description:

FacadeExample widget contains the SmartHomeState which hold the current state of smart devices and SmartHomeFacade to simplify the “smart actions”.

This widget only knows the simplified methods provided by the smart home facade but does not care about their implementation details, dependencies between classes or other facades and the amount of different APIs used to execute the single action. This allows implementing a complicated logic to handle the smart home actions just by turning the switch ON/OFF in ModeSwitcher widgets. Also, the implementation details of the smart devices’ handling methods in the SmartHomeFacade could be changed/improved without affecting the UI code.

The final result of the Facade design pattern’s implementation looks like this:

As you can see in the example, it is just enough to turn the switch on/off to communicate with multiple smart devices and change their state through the provided facade methods.

All of the code changes for the Facade design pattern and its example implementation could be found here.



Your contribution

👏 Press the clap button below to show your support and motivate me to write better!
💬 Leave a response to this article by providing your insights, comments or wishes for the series.
📢 Share this article with your friends, colleagues in social media.
➕ Follow me on Medium.
⭐ Star the Github repository.

Flutter Community

Articles and Stories from the Flutter Community

Mangirdas Kazlauskas

Written by

Software Engineer | Flutter Enthusiast https://www.linkedin.com/in/mangirdas-kazlauskas/

Flutter Community

Articles and Stories from the Flutter Community

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade