Implementation using a pattern strategy

Pattern Strategy in Support of Different Databases

Strategy Pattern is a behavioral design pattern that allows choosing the behavior of an algorithm at runtime. In the context of an ORM (Object-Relational Mapping) system, this pattern is particularly useful for supporting multiple database systems, such as PostgreSQL and MySQL, without binding the DatabaseManager class to a specific database implementation.

Concept Overview

In my ORM system, the Strategy pattern is implemented using classes that encapsulate logic specific to each database. The DatabaseManager class acts as the context and dynamically selects the appropriate strategy depending on the database type. The strategy is a representation of various database operations adapted to a specific database (e.g., PostgreSQL or MySQL).

Code Implementation

Here’s how the Strategy pattern is applied in my system:

  1. DatabaseManager Class: The context class that holds a reference to the strategy object.

class DatabaseManager<DT extends DatabasesTypes> implements DatabaseManagerInterface<DT> {
    private _connectionData: ConnectionData;
    private _dataSource: DataSourceContextInterface<DT>;

    constructor(connectionData: ConnectionData, dataSource: DataSourceContextInterface<DT>) {
        this._dataSource = dataSource;
        this._dataSource.connectionData = this._connectionData;
        
        if (connectionData.type === DatabasesTypes.POSTGRES) {
            this._dataSource.database = new DataSourcePostgres() as unknown as DataSourceInterface<DT>;
        }

        if (this._connectionData.type === DatabasesTypes.MYSQL) {
            this._dataSource.database = new DataSourceMySql() as unknown as DataSourceInterface<DT>;
        }
    }
}
  • The DatabaseManager class initializes the corresponding DataSource based on the connectionData.type.

  • This class is the entry point that sets up the correct strategy.

  1. DataSourceContext class: A context for storing the strategy.

  • The DataSourceContext class allows you to dynamically set the strategy (database) using the database method.

  1. Specific Strategy (PostgreSQL): Implements operations specific to PostgreSQL.

  • DataSourcePostgres Class encapsulates all PostgreSQL-specific operations, such as table creation, migration management, and query handling.

  • By adhering to the DataSourceInterface, it ensures seamless switching between different database strategies in DatabaseManager.

Why the Strategy Pattern is Useful:

  1. Flexibility: The Strategy Pattern allows easy switching between different types of databases by simply selecting the appropriate strategy. This is particularly useful in systems that need to support multiple databases.

  2. Ease of Maintenance: By encapsulating database-specific logic in separate classes, I can manage and update each strategy independently. If PostgreSQL changes its API, I only need to update the DataSourcePostgres class without affecting other parts of the system.

  3. Scalability: As my ORM system grows and starts supporting more databases, I can add new strategies without needing to modify existing code. Simply implement a new DataSource class and connect it to DatabaseManager.

This approach provides adaptability to different database environments and ease of maintenance over time, making it a robust solution for handling complex database operations.

Last updated