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