@o_weisman が言うように; AF の主な欠点は拡張性ですが、その問題を設計パターンの方法 (一般的に発生する問題に対する一般的な再利用可能なソリューション) でカバーする手法があれば、デフォルトで AF の一部になります。したがって、文脈のないこの質問は有効な質問ではないと思います。
インターフェイスの変更を回避してクライアントを壊す 1 つの手法は、すべての要素の作成に 1 つの Create メソッドのみを使用することです。しかし、これは正式名称のあるパターンではないかと思います。
つまり、C# の場合:
namespace ConsoleApplication1
{
public enum Appearance
{
Win,
OSX
}
interface IButton
{
void Paint();
}
interface ITextBox
{
void Paint();
}
interface IGUIFactory
{
TElement CreateGUIElement<TElement>() where TElement : class;
}
class GUIFactory
{
public static IGUIFactory Create(Appearance lookAndFeel) {
if (lookAndFeel == Appearance.Win) { return new WinFactory(); }
if (lookAndFeel == Appearance.OSX) { return new OSXFactory(); }
throw new NotImplementedException();
}
}
abstract class AGUIFactory : IGUIFactory
{
public TElement CreateGUIElement<TElement>() where TElement : class
{
if (typeof(IButton) == typeof(TElement)) { return CreateButton() as TElement; }
if (typeof(ITextBox) == typeof(TElement)) { return CreateTextBox() as TElement; }
throw new NotImplementedException();
}
protected abstract IButton CreateButton();
protected abstract ITextBox CreateTextBox();
}
class WinFactory : AGUIFactory
{
protected override IButton CreateButton()
{
return new WinButton();
}
protected override ITextBox CreateTextBox()
{
return new WinTextBox();
}
}
class OSXFactory : AGUIFactory
{
protected override IButton CreateButton()
{
return new OSXButton();
}
protected override ITextBox CreateTextBox()
{
return new OSXTextBox();
}
}
class WinButton : IButton
{
public void Paint()
{
Console.WriteLine("Windown button paint");
}
}
class OSXButton : IButton
{
public void Paint()
{
Console.WriteLine("OSX button paint");
}
}
class WinTextBox : ITextBox
{
public void Paint()
{
Console.WriteLine("Windown TextBox paint");
}
}
class OSXTextBox : ITextBox
{
public void Paint()
{
Console.WriteLine("OSX TextBox paint");
}
}
class Program
{
static void Main()
{
IGUIFactory factory;
IButton btn;
ITextBox txb;
factory = GUIFactory.Create(Appearance.Win); //UserSettings.LookAndFeel
btn = factory.CreateGUIElement<IButton>();
txb = factory.CreateGUIElement<ITextBox>();
btn.Paint();
txb.Paint();
factory = GUIFactory.Create(Appearance.OSX);
btn = factory.CreateGUIElement<IButton>();
txb = factory.CreateGUIElement<ITextBox>();
btn.Paint();
txb.Paint();
Console.ReadLine();
}
}
}