The Dev Journey

Factory Method Pattern using Typescript

Factory Method pattern is one of the creational design patterns. It is also the most basic of all the design patterns.

Real world example

Lets consider a real-world scenario where you are developing logging system. The logging system must support different types of loggers such file, database or console loggers based on configuration.

Step-by-Step Implementation

  1. Define the logger interface i.e product interface
interface Logger {
    log(message: string): void;
}

2. Implement concrete loggers i.e concrete products

class FileLogger implements Logger {
    log(message: string): void {
        // Logic to write to a file
        console.log(`FileLogger: ${message}`);
    }
}

class DatabaseLogger implements Logger {
    log(message: string): void {
        // Logic to write to a database
        console.log(`DatabaseLogger: ${message}`);
    }
}

class ConsoleLogger implements Logger {
    log(message: string): void {
        // Logic to write to the console
        console.log(`ConsoleLogger: ${message}`);
    }
}

3. Define the Logger Factory Interface i.e Creator interface

interface LoggerFactory {
    createLogger(): Logger;
}

4. Implement concrete Logger Factory i.e Concrete Creators

class FileLoggerFactory implements LoggerFactory {
    createLogger(): Logger {
        return new FileLogger();
    }
}

class DatabaseLoggerFactory implements LoggerFactory {
    createLogger(): Logger {
        return new DatabaseLogger();
    }
}

class ConsoleLoggerFactory implements LoggerFactory {
    createLogger(): Logger {
        return new ConsoleLogger();
    }
}

5. Client Code

function logMessage(factory: LoggerFactory, message: string) {
    const logger = factory.createLogger();
    logger.log(message);
}

const fileLoggerFactory = new FileLoggerFactory();
const databaseLoggerFactory = new DatabaseLoggerFactory();
const consoleLoggerFactory = new ConsoleLoggerFactory();

logMessage(fileLoggerFactory, "This is a file log message.");
logMessage(databaseLoggerFactory, "This is a database log message.");
logMessage(consoleLoggerFactory, "This is a console log message.");

Explanation

  • Logger interface: Defines the log method that all loggers must implement.
  • Concrete Loggers: Implement the log for different logging mechanisms (file, database, console)
  • Logger factory interface: Defines createLogger method that all the logger factories must implement.
  • Concrete Logger factories: Implement the createLogger method to return instances of specific loggers.
  • Client Code: Uses the factory to create a logger and log a message, demonstrating how the Factory Method Pattern allows the client code to work with different types of loggers without knowing the details of their creation.

Given example should help you understand how the Factory Method pattern can be applied to create different types of loggers based on configuration, making the system more flexible and easier to extend.

Benefits

  1. You avoid tight coupling between creator and concrete product.
  2. Single Responsibility Principle. You can move the product creation code into one place in the program, making the code easier to support.
  3. Open/Closed Principle. You can introduce new types of products into the program without breaking existing client code.

One of the cons of using this pattern is that the code may become complicated since you need to introduce a lot of new subclasses to implement the pattern.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *