Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
TypeScript 4 Design Patterns and Best Practices

You're reading from  TypeScript 4 Design Patterns and Best Practices

Product type Book
Published in Sep 2021
Publisher Packt
ISBN-13 9781800563421
Pages 350 pages
Edition 1st Edition
Author (1):
 Theofanis Despoudis Theofanis Despoudis
Profile icon Theofanis Despoudis

Table of Contents (14) Chapters

Preface 1. Section 1: Getting Started with TypeScript 4
2. Chapter 1: Getting Started with Typescript 4 3. Chapter 2: TypeScript Core Principles 4. Section 2: Core Design Patterns and Concepts
5. Chapter 3: Creational Design Patterns 6. Chapter 4: Structural Design Patterns 7. Chapter 5: Behavioral Design Patterns 8. Section 3: Advanced Concepts and Best Practices
9. Chapter 6: Functional Programming with TypeScript 10. Chapter 7: Reactive Programming with TypeScript 11. Chapter 8: Developing Modern and Robust TypeScript Applications 12. Chapter 9: Anti-Patterns and Workarounds 13. Other Books You May Enjoy

Chapter 4: Structural Design Patterns

Structural design patterns are design patterns that help developers discover and implement more convenient ways to establish relationships between objects. They create abstractions to facilitate the cross-functional use of entities without introducing extra coupling. You will find that these patterns are widely used in the real world as they allow room for extensibility without sacrificing flexibility.

In this chapter, we will learn in depth what structural design patterns are and how you can utilize them in practice. Just like we explained the previous family of patterns, we will look at each of the structural design patterns one by one with comprehensive explanations and example use cases.

In this chapter, we are going to cover the following main topics:

  • Structural design patterns
  • Adapter pattern
  • Decorator pattern
  • Façade pattern
  • Composite pattern
  • Proxy pattern
  • Bridge pattern
  • Flyweight pattern
  • ...

Understanding structural design patterns

Structural design patterns follow a different approach compared to the creational ones. Their main characteristic is to structure objects in a way that is flexible and easy to extend. We can identify the following scenarios where structural design patterns can be used:

  • Adjusting the layout of the objects to form larger structures: You have existing objects and want to add new functionality to them either because the requirements have changed or for code improvement reasons. You don't want to make the entity too big or introduce extra or duplicated code, so you want to make it easy to extend those objects without adding much overhead.
  • Simplifying relationships between different entities: You have different objects that have some sort of a relationship between them. There are two main ways we can identify those relationships. An object can contain a reference to another object, which means that it is a has-a relationship. On...

Adapter pattern

The Adapter pattern deals with interfacing two different objects without changing their implementation part. You want to call new object methods using an existing interface but because they don't have something in common, you use a wrapper to connect them. Let's understand this concept in detail.

An Adapter is like a wrapper. It wraps one object in a new structure or interface that can be used in a client that expects that interface. This way, you can expand the usage of a particular object and make it work across incompatible interfaces.

We explain the fundamental reasons to use this pattern next.

When to use Adapter

In general terms, you want to use this pattern whenever you want to solve the following problems:

  • You have a client that expects an interface of type A but you have an object that implements type B: You don't want to implement interface A for the second object mainly because it is not suitable and because you cannot...

Decorator pattern

Decorator is a pattern that also acts as a wrapper but only focuses on a single object. It works by changing the existing behavior of the object at runtime without extending it using a subclass.

One analogy of this pattern is when you occupy a room and you want to embellish it with flowers. You do not alter anything in the room. Instead, you buy some flowers and make the room pretty and colorful. This is how Decorators work with objects as they enhance their behavior.

We will explain what we mean next.

When you have an object that performs some useful actions, and there is a requirement to include additional functionality when performing those actions, then it makes sense to use a Decorator pattern. The idea is to extend or decorate this object with additional functionality while keeping the original object intact. Decorator can also control when and how the original class method is called, so it can also be used as an access control mechanism.

When...

Façade pattern

Façade is a pattern that also wraps one or more interfaces and hides the complexities of using complex workflows under a simpler interface.

When you have some workflows that need to be orchestrated in a specific manner, such as calling one service and then the other under certain criteria, it's quite tricky to bring this logic across your components every time. With this pattern, you hide all those complexities behind an API and offer a simpler, more readable way to call those workflows. In simple terms, you use a function to wrap many service calls together so that the client will call it with fewer parameters.

One analogy of this pattern is having a smartphone, and you have to type the number you want to call. Instead of calling the number by typing it, you use quick actions to obtain a number from a list and you call the number when you tap on the quick action button. Although you can still manually enter the numbers, the UI Façade can carry...

Composite pattern

Composite is a pattern that offers an alternative way to define hierarchies of objects without using inheritance. Again, you want a pattern that avoids inheritance as much as possible because inheritance has many drawbacks in practice. This is one more case against it.

One analogy of this pattern is a company having different types of employee roles, forming a pyramid. Each person is an employee but they have different responsibilities and you can traverse the hierarchy from top to bottom. Using Composite, you want to define objects similar in nature and type, but without attaching too much business logic and behavior to each of them. You want to allow the clients to decide what to perform with this composition of objects. This allows the clients to treat all objects in the hierarchy uniformly.

When to use Composite

There are many reasons why you want to use this pattern and we especially recommend the following ones:

  • To represent a hierarchical model...

Proxy pattern

Proxy is an entity that wraps an object that you require delegating operations on. This entity acts as a permission guard and controls access to the proxied object, enhancing its functionality or preventing it from calling certain methods altogether. You can also use it as a Singleton by instantiating the object at the right time.

One analogy of this pattern is a company secretary accepting calls on behalf of the company director. They can regulate the flow of calls and may or may not forward them to the director based on who is calling and why. This pattern works very similarly to the Decorator pattern that you learned about earlier. It also wraps an object and provides it with extra functionality. With Decorator, you wrapped an object with the same interface and it decorated some of the method calls. You could also add more than one Decorator to the object. However, with Proxy, you usually allow only one proxy per object, and you use it for controlling its access...

Bridge pattern

Bridge is a structural design pattern that acts as a connecting point between an abstraction and its implementation. Instead of having a class implement a functionality, we try to separate it into two pieces. The first part is the abstraction (that is, common interface methods) and the second part is the implementation. This is one more pattern that avoids using inheritance and allows more implementors to be added in the future.

One analogy of this pattern is having a universal remote control that works with any TV, even with TVs that are yet to arrive on the market. As long as they communicate using a common interface, you can have different types of remote controls and different types of TVs.

Let's now learn when to use the Bridge pattern.

When to use Bridge

The main reasons to use Bridge are as follows:

  • To separate abstraction from implementation: So that at runtime you have the flexibility to choose the implementation without changing the...

Flyweight pattern

The last structural design pattern you will learn about in this chapter is Flyweight. This pattern deals with managing efficient usage of memory or space resources by allocating some of the objects internally. At times, when you frequently use objects such as strings or cache values from numerous clients, it becomes enormously expensive to generate them on the fly every time. With this pattern, you provide an interface, so the client can still benefit from using those objects but share them as well as much as possible behind the scenes.

One analogy of this pattern is sharing a few traditional costumes among many dancers. Because those costumes are very expensive to buy sometimes, some of the dancers may have to buy new ones but some may distribute them between performances. The manager, for example, takes the role of the Flyweight and decides when they need to purchase new ones or share existing ones. Justifying why and how you should conserve memory resources...

Summary

This chapter demonstrated all the fundamental aspects of structural design patterns and how to utilize them effectively in practice. These patterns focus on the internal and external composition of classes and how they share implementations.

We started with discovering the details of the Adapter pattern and how it helps make classes work with others by implementing a common interface. Then, we explored the Bridge pattern, which allows us to separate and abstract from its implementation. Using the Decorator and Proxy patterns, you can enhance the functionality of the objects at runtime without using inheritance. Then we explored how the Façade pattern uses a simpler interface to control complex workflows. By structuring a group of objects as composites, you can create a hierarchical system that shares a common interface. Lastly, using the Flyweight pattern, you learned how to use a shared state to minimize memory usage or space.

Using these patterns will help you...

Q&A

  1. How is Façade different compared to the Proxy pattern?

    Façade shares some common characteristics of the Proxy pattern. However, Façade does not need to have the same interface as the service objects or subsystems it tries to encapsulate.

  2. How is Decorator different compared to the Proxy pattern?

    Both patterns are fairly similar but they have different functionalities and responsibilities. Decorator is used by the client to wrap an object and can be added or removed at runtime. With Proxy, the client does not usually have this flexibility as it is usually hidden from the client. This means that the client can only interface with the proxy and has limited control over the underlying object instance.

  3. How is Bridge different compared to the Adapter pattern?

    Adapter is used on an existing app to make some incompatible classes work together. This means that you can write Adapters on top of existing programs. Bridge, however, needs more design up front as you...

Further reading

lock icon The rest of the chapter is locked
You have been reading a chapter from
TypeScript 4 Design Patterns and Best Practices
Published in: Sep 2021 Publisher: Packt ISBN-13: 9781800563421
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime}