Design Patterns

Example 2: Database Access

Consider an application that needs to support multiple database types (e.g., SQL Server and Oracle).

Step 1: Abstract Factory: Interface for creating database connections and commands.

public interface IDatabaseFactory
{
    IDbConnection CreateConnection();
    IDbCommand CreateCommand();
}

Step 2: Concrete Factory: Implementations for SQL Server and Oracle.

public class SqlServerFactory : IDatabaseFactory
{
    public IDbConnection CreateConnection() => new SqlConnection();
    public IDbCommand CreateCommand() => new SqlCommand();
}

public class OracleFactory : IDatabaseFactory
{
    public IDbConnection CreateConnection() => new OracleConnection();
    public IDbCommand CreateCommand() => new OracleCommand();
}

Step 3: Abstract Product: Interfaces for connections and commands.

public interface IDbConnection
{
    void Connect();
}

public interface IDbCommand
{
    void Execute();
}

Step 4: Concrete Product: Implementations for SQL Server and Oracle.

public class SqlConnection : IDbConnection
{
    public void Connect()
    {
        Console.WriteLine("Connecting to SQL Server.");
    }
}

public class SqlCommand : IDbCommand
{
    public void Execute()
    {
        Console.WriteLine("Executing SQL Server command.");
    }
}

public class OracleConnection : IDbConnection
{
    public void Connect()
    {
        Console.WriteLine("Connecting to Oracle.");
    }
}

public class OracleCommand : IDbCommand
{
    public void Execute()
    {
        Console.WriteLine("Executing Oracle command.");
    }
}

Step 5: Client: Uses the abstract factory to create and use database objects.

public class DatabaseApplication
{
    private readonly IDatabaseFactory _factory;
    private IDbConnection _connection;
    private IDbCommand _command;

    public DatabaseApplication(IDatabaseFactory factory)
    {
        _factory = factory;
    }

    public void Initialize()
    {
        _connection = _factory.CreateConnection();
        _command = _factory.CreateCommand();
    }

    public void Run()
    {
        _connection.Connect();
        _command.Execute();
    }
}

Step 6: Example Usage

public class Program
{
    public static void Main(string[] args)
    {
        IDatabaseFactory factory;
        if (args[0] == "SQLServer")
        {
            factory = new SqlServerFactory();
        }
        else
        {
            factory = new OracleFactory();
        }

        var app = new DatabaseApplication(factory);
        app.Initialize();
        app.Run();
    }
}