4

インタビューで次の質問に直面しましたが、Google またはスタック オーバーフローで解決策が見つかりませんでした。それが本当に有効な質問かどうかはわかりません(コンテキストが与えられなかったので、彼が話していたコンテキストで)??

私は、Abstract Factory パターンのよく知られた問題と、その問題に対処するパターンを教えてほしいと頼まれました。

それで、その問題が正確に何であるかを理解するのを手伝ってくれる人はいますか(秘密)

抽象工場設計パターンの短所は何ですか?

私はこのリンクを通過しましたが、Abstract Factory の欠点に対処する他のパターンを特定できませんでした。

4

3 に答える 3

2

GoF (一種のプログラマーの聖書) による「デザイン パターン」からの引用:新しい種類の製品をサポートするには、ファクトリ インターフェイスを拡張する必要があります。これには、AbstractFactory クラスとそのすべてのサブクラスの変更が含まれます。

于 2016-09-05T07:41:43.503 に答える
1

@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();
    }
  }

}
于 2016-09-06T05:53:19.817 に答える