Design Patterns in Angular
Last Updated :
05 Jan, 2024
Design patterns are communicating objects and classes that are customized to solve a general design problem in a particular context. Design patterns are general, reusable solutions to common problems that arise during the design and development of software. They represent best practices for solving certain types of problems and provide a way for developers to communicate about effective design solutions.
Important Topics For The Design Patterns In Angular
What are common Angular Design Patterns?

Singleton pattern is a design pattern which restricts a class to instantiate its multiple objects. It is nothing but a way of defining a class. Class is defined in such a way that only one instance of the class is created in the complete execution of a program or project. It is used where only a single instance of a class is required to control the action throughout the execution. A singleton class shouldn’t have multiple instances in any case and at any cost.
Example:
Singleton classes are used for logging, driver objects, caching and thread pool, database connections.
Below is the implementation of Singleton Pattern:
JavaScript
class SingletonService {
private static instance: SingletonService;
private constructor() {
// Private constructor to prevent instantiation.
}
public static getInstance(): SingletonService {
if (!SingletonService.instance) {
SingletonService.instance = new SingletonService();
}
return SingletonService.instance;
}
}
const singletonInstance = SingletonService.getInstance();
Why Singleton Pattern is useful in Angular?
Using Singleton Pattern in Angular ensures a single instance of a service throughout the application, optimizing resource usage and providing a centralised location for managing global state and shared functionality.
The Factory Method pattern is used to create objects without specifying the exact class of object that will be created. This pattern is useful when you need to decouple the creation of an object from its implementation. The idea is to create a factory class with a single responsibility to create objects, hiding the details of class modules from the user.
A factory pattern is one of the core design principles to create an object, allowing clients to create objects of a library in a way such that it doesn’t have a tight coupling with the class hierarchy of the library.
What is meant when we talk about libraries and clients?Â
- A library is something that is provided by some third party that exposes some public APIs and clients make calls to those public APIs to complete their tasks.
- A very simple example can be different kinds of Views provided by Android OS.Â
Example:
A logging system with flexibility to use different output methods. Create two loggers, one for the console (ConsoleLogger
) and another for file output (FileLogger
), both implementing a common interface (Logger
). Implement a factory method (createLogger
) that dynamically generates the desired logger based on specified types ('console' or 'file'), allowing the client code to easily switch between logging methods.
Below is the implementation of Factory Pattern:
JavaScript
interface Logger {
log(message: string): void;
}
class ConsoleLogger implements Logger {
log(message: string): void {
console.log(message);
}
}
class FileLogger implements Logger {
log(message: string): void {
// Log to a file.
}
}
// Factory method
function createLogger(type: 'console' | 'file'): Logger {
if (type === 'console') {
return new ConsoleLogger();
} else if (type === 'file') {
return new FileLogger();
}
}
const consoleLogger = createLogger('console');
consoleLogger.log('Logging to console');
Why Factory Pattern is useful in Angular?
Using Factory Pattern in Angular enables dynamic creation of instances based on conditions or configurations, promoting flexibility, and allowing for the creation of related objects without specifying their exact class.
Prototype allows us to hide the complexity of making new instances from the client. The concept is to copy an existing object rather than creating a new instance from scratch, something that may include costly operations.
- The existing object acts as a prototype and contains the state of the object.
- The newly copied object may change same properties only if required.
- This approach saves costly resources and time, especially when object creation is a heavy process.
Example:
Imagine you have a complex object with a configuration that is time-consuming to set up. Instead of creating a new instance and configuring it from scratch each time, you can use a prototype to clone an existing instance, preserving its state.
Below is the implementation of Prototype Pattern:
JavaScript
interface Prototype {
clone(): Prototype;
}
class ConcretePrototype implements Prototype {
private property: string;
constructor(property: string) {
this.property = property;
}
clone(): Prototype {
return new ConcretePrototype(this.property);
}
}
const originalObject = new ConcretePrototype('Original');
const clonedObject = originalObject.clone();
Why Prototype Pattern is useful in Angular?
Using Prototype pattern in Angular facilitates the creation of new objects by copying an existing object, reducing the need for complex instantiation logic and promoting efficient object creation, especially in scenarios where object initialization is resource-intensive.
The adapter pattern convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces. To use an adapter:
- The client makes a request to the adapter by calling a method on it using the target interface.
- The adapter translates that request on the adaptee using the adaptee interface.
- Client receive the results of the call and is unaware of adapter’s presence.
Example:
Integrate a new logging system (NewLogger
) with an existing class (OldLogger
) that has a different interface. An adapter (Adapter
) that allows the old logging functionality to be used seamlessly through the new logging interface, ensuring compatibility and facilitating the transition to an updated logging system.
Below is the implementation of Adapter Pattern in Angular:
JavaScript
interface NewLogger {
logMessage(message: string): void;
}
class OldLogger {
log(msg: string): void {
console.log(msg);
}
}
class Adapter implements NewLogger {
private oldLogger: OldLogger;
constructor(oldLogger: OldLogger) {
this.oldLogger = oldLogger;
}
logMessage(message: string): void {
this.oldLogger.log(message);
}
}
const oldLogger = new OldLogger();
const loggerAdapter = new Adapter(oldLogger);
loggerAdapter.logMessage('Logging with adapter');
Why Adapter Pattern is useful in Angular?
Using Adapter pattern in Angular allows incompatible interfaces to work together, acting as a bridge between different components. In Angular, decorators often serve as adapters, modifying or extending the behavior of classes without changing their core implementation.
A structural design sample known as the Decorator Pattern allows behavior to be introduced to a character object in a statically or dynamically way without influencing the behavior of other objects in the same class.
- The decorator pattern attaches additional responsibilities to an object dynamically.
- Decorators provide a flexible alternative to subclassing for extending functionality.
Example:
Let us assume a flexible and extensible system for calculating the cost of customized coffee orders. Define a base coffee interface (Coffee
) with a cost
method. Create concrete coffee classes (SimpleCoffee
) and decorators (MilkDecorator
, SugarDecorator
) that enhance the cost based on added ingredients. Demonstrate the decorator pattern by composing various decorator instances, allowing clients to dynamically customize and calculate the cost of their desired coffee combinations.
Below is the implementation of Decorator Pattern:
JavaScript
interface Coffee {
cost(): number;
}
class SimpleCoffee implements Coffee {
cost(): number {
return 5;
}
}
class MilkDecorator implements Coffee {
private coffee: Coffee;
constructor(coffee: Coffee) {
this.coffee = coffee;
}
cost(): number {
return this.coffee.cost() + 2;
}
}
class SugarDecorator implements Coffee {
private coffee: Coffee;
constructor(coffee: Coffee) {
this.coffee = coffee;
}
cost(): number {
return this.coffee.cost() + 1;
}
}
const myCoffee = new SugarDecorator(new MilkDecorator(new SimpleCoffee()));
console.log(myCoffee.cost()); // Output: 8
Why Decorator Pattern is useful in Angular?
Using Decorator Pattern in Angular enhances classes dynamically by attaching new behaviors or responsibilities, providing a flexible and reusable way to extend functionality. In Angular, decorators are commonly used to add metadata or modify the behavior of components, services, and directives.
Accessing the components of a combination item in a sequential manner without disclosing its underlying representation is made possible by the Iterator pattern. This can be useful when using Angular to iterate across collections.
Example:
An iterator mechanism to traverse the elements sequentially. Define a generic interface (Iterator<T>
) with methods for retrieving the next element and checking if there are more elements. Create a concrete iterator class (ConcreteIterator<T>
) that operates on a collection of elements, enabling clients to iterate over the collection in a systematic way.
Below is the implementation of Iterator Pattern:
JavaScript
interface Iterator<T> {
next(): T;
hasNext(): boolean;
}
class ConcreteIterator<T> implements Iterator<T> {
private collection: T[];
private index: number = 0;
constructor(collection: T[]) {
this.collection = collection;
}
next(): T {
return this.collection[this.index++];
}
hasNext(): boolean {
return this.index < this.collection.length;
}
}
const iterableCollection = [1, 2, 3, 4, 5];
const iterator = new ConcreteIterator(iterableCollection);
while (iterator.hasNext()) {
console.log(iterator.next());
}
Why Iterator Pattern is useful in Angular?
Using Iterator Pattern in Angular simplifies the traversal of collections or lists, providing a standardized way to access elements sequentially.
A state design pattern is used when an Object changes its behavior based on its internal state. If we have to change the behavior of an object based on its state, we can have a state variable in the Object and use the if-else condition block to perform different actions based on the state. The state pattern is used to provide a systematic and lose-coupled way to achieve this through Context and State implementations.
Example:
A state machine system where an object (Context
) can change its behavior as it transitions through different states. Define a common interface (State
) for various states, each implementing a handleRequest
method. Implement concrete state classes (ConcreteStateA
, ConcreteStateB
) representing distinct behaviors. The Context
class maintains the current state and delegates requests to the current state. Display initializing the context with one state, transitioning to another state, and observing the change in behavior upon requests.
Below is the implementation of State Pattern:
JavaScript
interface State {
handleRequest(): void;
}
class ConcreteStateA implements State {
handleRequest(): void {
console.log('Handling request in State A');
}
}
class ConcreteStateB implements State {
handleRequest(): void {
console.log('Handling request in State B');
}
}
class Context {
private state: State;
constructor(state: State) {
this.state = state;
}
setState(state: State): void {
this.state = state;
}
request(): void {
this.state.handleRequest();
}
}
const context = new Context(new ConcreteStateA());
context.request(); // Output: Handling request in State A
context.setState(new ConcreteStateB());
context.request(); // Output: Handling request in State B
Why State Pattern is useful in Angular?
Using State Pattern in Angular allows an object to alter its behavior when its internal state changes, promoting a clean separation of concerns. In Angular, services or RxJS observables are used to manage state, making it easier to handle different application states and behaviors.
Conclusion
- As a software developer, it's essential to know different design styles.
- In Angular optimization, using these principles can make your code more organized, scalable, and easy to maintain.
- Design patterns provide smart solutions to common web development issues, whether you're dealing with a single feature or adding more functions dynamically.
- Remember to use these patterns to make your programs strong and adaptable as you work with Angular.
Similar Reads
How to use Mat-Dialog in Angular ?
Introduction:Angular Material is a UI component library that is developed by the Angular team to build design components for desktop and mobile web applications. In order to install it, we need to have angular installed in our project, once you have it you can enter the below command and can downloa
3 min read
Angular PrimeNG OrderList Templates
Angular PrimeNG is an open-source framework with a rich set of native Angular UI components that are used for great styling and this framework is used to make responsive websites with very much ease. In this article, we will learn about Angular PrimeNG OrderList Templates. The Orderlist component is
3 min read
What is Angular Expression ?
Angular is a great, reusable UI (User Interface) library for developers that help in building attractive, and steady web pages and web application. In this article, we will learn about Angular expression. Table of Content Angular ExpressionDifferent Use Cases of Angular ExpressionsSyntaxApproach Ang
4 min read
How to use mat-icon in angular?
To include icons in your webpage, you can use mat-icon directive. Previously it was known as md-icon. It is better to use mat-icon as they serve SVG icons i.e. vector-based icons which are adaptable to any resolution and dimension, on the other hand, raster-based icons have a fixed pattern of dots w
2 min read
Binding Syntax In Angular
In Angular, binding syntax lets you determine the channel of data transmission between the component class and the template. Among various types of bindings supported by Angular are interpolation, property binding, event binding, and two-way-data-binding. Therefore, it is important to understand var
3 min read
Weather App Using Angular
We will be creating a weather application using the Angular framework. This app will allow users to check the current weather conditions by entering a city name. It will provide detailed information including temperature, weather description, wind speed, and humidity. With responsive design and inte
9 min read
Angular PrimeNG Galleria Templates
Angular PrimeNG is an open-source framework with a rich set of native Angular UI components that are used for great styling and this framework is used to make responsive websites with very much ease. It provides a lot of templates, components, theme design, an extensive icon library, and much more.
4 min read
Angular Material Installation
Angular Material is a popular UI framework for building user interfaces with the Material Design style, widely used by web developers around the world. It is a set of reusable UI components and guidelines for building web applications with the Material Design language, which is developed by Google.
5 min read
Angular Versions
Angular has been an essential framework in web development, enabling developers to build dynamic and responsive web applications. Since its launch, Angular has evolved, introducing new features, performance improvements, and enhanced capabilities. Understanding the different versions of Angular and
4 min read
What is scope in AngularJS ?
In this article, we will see what the scope is in AngularJS and how to use Scope, along with understanding its implementation through the examples. The Scope in AngularJS is the binding part between HTML (view) and JavaScript (controller) and it is a built-in object. It contains application data and
4 min read