Design Patterns for Smart Homes

Applying Singleton, Builder, Composite, and Abstract Factory Patterns for Smart Home Devices in TypeScript

In this lesson, we will integrate design patterns into a practical project: building a smart home system. You'll learn how to create and adapt various smart home devices using the Singleton, Builder, Composite, and Abstract Factory patterns in TypeScript. By the end, you will have a solid understanding of how these design patterns, combined with TypeScript's type system, can make your smart home system more efficient, modular, and easier to maintain.

Quick Summary

  1. Singleton Pattern:

    • Purpose: Ensures a class has only one instance and provides a global point of access to it.
    • TypeScript Features: Use private constructors, static properties, and type annotations to enforce singleton behavior.
  2. Builder Pattern:

    • Purpose: Constructs complex objects step by step, providing a flexible solution for object creation.
    • TypeScript Features: Use classes, interfaces, and method chaining with type annotations for clarity and safety.
  3. Composite Pattern:

    • Purpose: Treats individual objects and compositions of objects uniformly.
    • TypeScript Features: Use interfaces or abstract classes to define a common contract for components and leverage type safety for composite structures.
  4. Abstract Factory Pattern:

    • Purpose: Provides an interface for creating families of related or dependent objects without specifying their concrete classes.
    • TypeScript Features: Use abstract classes or interfaces to define factories and product types, ensuring type-safe object creation.

Implementing the Singleton Pattern

To start, we implement the Singleton pattern in TypeScript to ensure that a class has only one instance and provides a global point of access to it. TypeScript's private constructors and static properties help enforce this pattern.

class Singleton {
    private static instance?: Singleton;

    // Private constructor prevents direct instantiation
    private constructor() {
        // Additional initialization code can go here
    }

    public static getInstance(): Singleton {
        if (Singleton.instance === undefined) {
            Singleton.instance = new Singleton();
        }
        return Singleton.instance;
    }
}

// Usage
const singleton1 = Singleton.getInstance();
const singleton2 = Singleton.getInstance();
console.log(singleton1 === singleton2);  // Output: true

The instance property is now typed as Singleton | undefined, and the check uses undefined, which is more idiomatic in TypeScript.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal