Frontend Architecture — Facade Pattern and Restricting Libraries
Front-end projects are growing larger and larger. Today almost
every new application is created in browsers with JavaScript technologies.
Unfortunately, good architecture and well structured code were always
considered less important in front-end projects. As a result, creating an
application without following good practices and restrictions can lead to
significant technical debt, which makes it difficult or impossible to extend
the project in the long run.
Not implementing an appropriate structure can cost a lot in terms of
time and money. Therefore, starting blindly on development work and
prioritising time over quality might not always be the best approach.
In this article, I’d like to talk about using a Facade Pattern [2]
because this is one of the best and easiest ways of simplifying most front-
end projects. What is a Facade Pattern? In short, it’s a way of reducing the
complexity of an external dependency down to only the elements that are
required in our current code base. Most examples refer to using this
approach when creating interfaces, but it’s also possible to use this
approach when working with React Components.
What does a project look like when we don’t take care of the front-
end architecture from the beginning? It is easy to extend simple
applications or proofs of concept by just adding more functionalities. In
these cases, one small feature is usually added to an application one at a
time over a period of years. This process can lead to unmaintainable
projects or what is sometimes called a “Spaghetti Monster”. Unfortunately, this is the result of a naive approach that is based on little
or no planning. Being in this position can be tough. It’s the result of just
quickly adding new features one after the other. When the speed of
delivery matters most, there is little time for overall improvements. This
behaviour can lead to the project having more and more technical debt.
Unfortunately, technical debt doesn’t stay hidden in the background
forever, but shows itself in increasingly slower delivery times and constant
regressions that then result in almost infinite maintenance bug-repair
loops.
Example no. 1 above shows how a project can look when you don’t
follow any good practices or implement any restrictions.
Common mistakes made by developers:
1. Inadvertently introducing multiple libraries (Material UI, Ant Design etc.) that do the same thing.
2. Implementing components on the spot with large configurations.
Why should we reduce complexity by using a Facade Pattern? In
front-end applications, it’s common to use external UI libraries like Ant
Design to implement components, and its typical for this type of library to
be generic. This makes sense because these libraries need to be able to
meet most use cases that it will be applied to, whilst also making it
possible for the programmer to customize certain elements, for example,
styling.
The downside of using these pre-prepared solutions is that they can
require a lot of configuration just to fit into our application. It’s not a
mystery that applications can grow rapidly and, as a result, it will get
harder and harder to maintain common views using similar components.
And this is especially true when it comes to dealing with changes and
bugs. I believe that small, one line differences in the configuration of
similar components are the most common bugs that can eat into a
developer’s valuable time. Another disadavantage is readability because,
if you have to go through the multiple configuration lines of similar
components, then this can be a nightmare. The next issue can arise when
updating the libraries because some configuration parameters can change
and break our application, which then forces the developer to update
every component where the breaking change occurred. All this leads to
having a business code base that is too dependent on an external library.
This adds risk to the continuing existence of the project and also to your
ability to extend the project. In Software Architecture terminology, this
phenomenon is commonly known as ‘getting married to an external
dependency’, which is something that might later hit the project in
negative terms [1]. You should therefore create your applications on solid
foundations instead of foundations based on the ‘latest thing’, hype or
poorly supported libraries. Try to rely only on solid technology, such
as .Net and React.
Example no. 2 shows a simple example of facade pattern
implementation. In this case, we first create a common implementation in
a single, shared place for Ant Design Table and Form Components. These
common components will hide the complex configuration for the external
Ant Design Library. Most of the other functionality won’t even be used, but
we do wish to have the same user experience for similar looking
components in our application. Using these common components we can
create individual instances of Tables and Forms in our application code
base, but now we can do this in one place without pulling in a whole lot of
complexity. Compare this approach to the architecture shown in example
1, where you have to change something like pagination in every Table in
the application. What a nightmare that would be!
Why should we restrict the usage of external libraries? Introducing a
whole new library just to make a single element in a project can lead to
weird mixes. Instead, adding a new dependency should be part of a well-
thought process. I find it common for developers to introduce another big
library to the project just to implement some solution in order to avoid the
task of first reviewing the existing tech stack for similar tools. Typically,
developers take such action without consulting others, which is a bad
practice. Every technical decision should be discussed with the
development team that is working together on the same project. Why
wouldn’t you do that anyway? And there is nothing worse than having to
deal with multiple tables or button components that come from different
libraries, and then trying to make them work in a similar way for the user.
Conclusions
It’s a fact that front-end technologies are growing faster and faster.
Everyone is now used to working in browsers and wants to be able to use
all applications inside a browser. Having a good, readable and well-
structured front-end project is therefore a necessity these days.
Prioritising time over quality is a poor practice that can lead to
unmaintainable and unreadable projects. It’s important to plan and
forecast future needs in order to be able to smoothly implement the next
set of changes or extensions when this becomes necessary. Implementing
a simple Facade Pattern and restricting ourselves to a single tech stack
can be an easy way of improving the project for the future. I encourage
you to research and use the correct patterns when needed. As a result,
you can avoid unnecessary overheads that come from automatically
generating redundant boilerplate code.
Sources:
[1] Robert C. Martin, Clean Architecture: A Craftsman’s Guide to Software
Architecture and Design, 978–83–283–4225–5, Helion 2018
[2] Refactoring Guru, Structural Pattern Facade
https://refactoring.guru/design-patterns/facade/