C#でデザインパターン「AbstractFactoryパターン」

C# コンピュータ
C#

GUIのアプリケーションを作成する場合、ButtonやLabelなどのコントロールを配置すると思いますが、OSなどプラットフォームごとに生成するオブジェクトが異なる場合でも、生成する過程を抽象化することで同じ生成コードが適用できるようにするパターン

/// <summary>
/// AbstractFactoryパターンのサンプルコード
/// </summary>
interface IButtonBase
{
    public void Display();
}
interface ILabelBase
{
    public void Display();
}
class WinButton : IButtonBase
{
    public void Display()
    {
        Console.WriteLine("WinButton.Display");
    }
}

class WinLabel : ILabelBase
{
    public void Display()
    {
        Console.WriteLine("WinLabel.Display");
    }
}

class LinuxButton : IButtonBase
{
    public void Display()
    {
        Console.WriteLine("LinuxButton.Display");
    }
}

class LinuxLabel : ILabelBase
{
    public void Display()
    {
        Console.WriteLine("LinuxLabel.Display");
    }
}

interface IGuipartFactgory
{
    public IButtonBase CreateButton();
    public ILabelBase CreateLabel();
}

class WinGuipartFactory : IGuipartFactgory
{
    public IButtonBase CreateButton()
    {
        return new WinButton();
    }
    public ILabelBase CreateLabel()
    {
        return new WinLabel();
    }
}

class LinuxGuipartFactory : IGuipartFactgory
{
    public IButtonBase CreateButton()
    {
        return new LinuxButton();
    }
    public ILabelBase CreateLabel()
    {
        return new LinuxLabel();
    }
}

class Application
{
    IButtonBase _button;
    ILabelBase _label;
    public Application(IGuipartFactgory factory)
    {
        _button = factory.CreateButton();
        _label = factory.CreateLabel();
    }
    public void Display()
    {
        _button.Display();
        _label.Display();
    }
}
class Program
{
    static public void Main()
    {
        string platform = "Linux"; // or "Win"

        IGuipartFactgory factory;

        if ("Win" == platform)
        {
            factory = new WinGuipartFactory();
        } else if ("Linux" == platform) {
            factory = new LinuxGuipartFactory();
        } else {
            throw new PlatformNotSupportedException($"未対応のプラットフォーム:{platform}");
        }

        Application app = new Application(factory);
        app.Display();
    }
}

インターフェイスを使うことで、オブジェクトの実装は後回しにして、オブジェクトを使う側のクライアントコードを先に作ることが出来ます。具体的な実装を後から作れるから、テストコードを書いたり、バックエンドシステムの切り替えなどに都合の良いパターンだと思います。

コメント