GoFデザインパターン-実際にどのパターンを使用しますか?[閉まっている]


16

デザインパターンの分野で同僚を教育しようとしています。オリジナルのGang of Fourパターンの一部は少し難解なので、すべてのプログラマーが知っておくべき「必須」パターンのサブグループがあるのではないかと思っています。リストを見ると、おそらく使用したと思う-

  • 抽象工場
  • 工場工法
  • シングルトン
  • ブリッジ
  • ファサード
  • コマンド

実際にどれを実際に使用しますか、また何に使用しますか?

パターンのリストが必要な人のためのリンク


7
私見、質問は有用な議論をもたらすには曖昧すぎる。パターンごとに1つの回答が必要ですか、パターンの組み合わせごとに1つの回答が必要ですか?
マッケ

これらのパターンを使用する理由はいくつかありますが、そうでない場合は概念をリストするだけです。「どのキーワードを使用しますか?」という質問をすると想像してください。for, if, while...etc」のリストの収集-それがどれほど無意味であるかを測定することは困難です。
オコド

1
Slomojoには同意しません-どのキーワードが一般的に使用され、どのキーワードが言語にないかを知ることは非常に便利だと思います。たとえば、基本クラスについても同様です。
クレイグシュヴァルツェ

1
それをもう少し修正しました-これが今より良い議論を生むことを願っています。
クレイグシュヴァルツェ

1
実際にどのような果物を食べますか?この質問からあなたが何を望んでいるのか知りたいです。3人または4人が使用したが、使用していないパターンが表示された場合、それを使用することになりますか?
マーシー

回答:


4

以下は、私が実際に使ったり見たりしたもののリストです。

シングルトン-ASP.Netのアプリケーションオブジェクトは、この典型的な例です。

アダプター-データベースへの接続には、通常、少なくとも.Netの分野ではアダプタークラスを使用できます。

工場-オブジェクトを生成するための一般的な方法ですが、昔の古いASPでこれを見たことがあります。

戦略-各タイプのデバイスに対して、このパターンの実装を検討するクラスに対して同様の構造を持つアプリケーションがありました。

ファサード-いくつかの点で、これは通常いくつかのシステムを結び付けるものであるという点で、アダプターパターンに似ています。


1
すべての有効な使用。これも読んでいる人にとっては-これらのパターンは確かにこれらに限定されないことに留意してください。
ボリスヤンコフ

5

著者は、実際のアプリケーションで見つかった観察されたデザインからパターンをコンパイルしました。誰もそれらのすべてを使用することはないでしょうが、それらはすべて使用されています。


スミスコはどちらを使用しましたか?
クレイグシュヴァルツェ

@CraigS私はそれらの多くを使用しました。Design Patternsの作成者には、説明する各パターンの良い例があります。最善の提案は、時間をかけて本をよく読むことです。
スミスコ

3

デコレータ

編集:「些細な」段階を超えるほとんどすべてのプロジェクトで、IActionインターフェースになります(詳細は異なる場合があります)。

// Programming Language does not matter
interface IAction {
     bool operateOn(Foo* target);
     string getDisplayName(); // useful for debugging and logging
};

次の1時間は、IActionを実装する多くの小さな、ささいなクラスを書くことに費やします。組み合わせると、非常に強力で柔軟です。

たとえば、LogAction(ログへの書き込みとIActionの実行)、NullAction(何もせずにtrueを返す)、ActionList(IActionのリストを実行し、ブールのANDを返します)。いくつかのケースではAndAction(、2つの動作のAND-INGのを返す短絡またはない可能性があり)、 OrActionNotActionメイク感覚にも。

技術的には上記の例ではLogActionのみがデコレーターです(もう1つはちょうど1つのIActionで動作しません)が、IActionsのLogActionsのActionListを作成するときは、これもデコレーターパターンの一般化と考えます。


何に使うのさ?
クレイグシュヴァルツェ

1
要求に応じて@CraigSの例が追加されました。
シェード

それは罰金である、実際にはより多くのデコレータおよびコンポジットのミックスのように見える、とパターンの難しさは、独立して、それらを使用してから来ていないことを完璧なデモが、それらを一緒に混合から:)
マシューM.

はい、これは古典的なものです。コマンドと比較したコンポジットです。このパターンには実際には名前があります。「仕様」と呼ばれます(en.wikipedia.org/wiki/Specification_pattern)。
マーティンウィックマン

2

私はあなたが質問を自分のコード/プロジェクトでのパターンの使用に制限することを意味すると仮定します(クラスライブラリとサードパーティのフレームワークはありません)。

他の人と同様に、私はFactoryパターンを最も頻繁に使用しました。それから

  • シングルトン:最近ではあまりありませんが、それでも必要な場合があります。通常はグローバル構成データに
  • 戦略テンプレートの方法:非常に頻繁に、たとえば、アプリでさまざまな種類の計算を表すために
  • Builder:メインフレームシステムとのトランザクションの結果を出力オブジェクトにマーシャリングします(場合によっては、大量のテキスト解析と大きなオブジェクト階層の作成が含まれます)
  • Command:数年前に一度だけ実装しましたが、最近のJavaプロジェクトでは、時々Callablesを使用しています。これは基本的にCommand

2

私はすでに言及されている他の多くを使用しました(シングルトン、ファクトリー、ビルダー、コマンド、ストラテジーなど)

まだ言及されていないものの1つはフライウェイトで、これはよく使う傾向があります。以下に実装例を示しました。

/**
 * Flyweight class representing OCR digits.
 * 
 * @author matt
 *
 */
public class Digit {
    /** Static flyweight map containing Digits which have been encountered. **/
    private static Map digits = new HashMap();

    /** The block of text representing Digit. **/
    private String blockRep = null;

    /** A map representing acceptable blocks of characters and the string representation of their
     * numerical equivalents.
     */
    public static final Map VALID_DIGITS;

    /** Enum of valid digits. **/
    public static enum DigitRep {
        ZERO    (   " _ \n" +
                    "| |\n" +
                    "|_|"       ),

        ONE (       "   \n" +
                    "  |\n" +
                    "  |"       ),

        TWO (       " _ \n" +
                    " _|\n" +
                    "|_ "       ),

        THREE   (   " _ \n" +
                    " _|\n" +
                    " _|"       ),

        FOUR    (   "   \n" +
                    "|_|\n" +
                    "  |"       ),

        FIVE    (   " _ \n" +
                    "|_ \n" +
                    " _|"       ),

        SIX     (   " _ \n" +
                    "|_ \n" +
                    "|_|"       ),

        SEVEN   (   " _ \n" +
                    "  |\n" +
                    "  |"       ),

        EIGHT   (   " _ \n" +
                    "|_|\n" +
                    "|_|"       ),

        NINE    (   " _ \n" +
                    "|_|\n" +
                    " _|"       );

        private String blockRep;

        DigitRep(String blockRep) {
            this.blockRep = blockRep;
        }

        @Override
        public String toString() {
            return blockRep;
        }
    }

    static {
        /* Initialize the map of acceptable character blocks. */
        Map tmpMap = new HashMap();
        tmpMap.put( DigitRep.ZERO.toString(),   "0");
        tmpMap.put( DigitRep.ONE.toString(),    "1");
        tmpMap.put( DigitRep.TWO.toString(),    "2");
        tmpMap.put( DigitRep.THREE.toString(),  "3");
        tmpMap.put( DigitRep.FOUR.toString(),   "4");
        tmpMap.put( DigitRep.FIVE.toString(),   "5");
        tmpMap.put( DigitRep.SIX.toString(),    "6");
        tmpMap.put( DigitRep.SEVEN.toString(),  "7");
        tmpMap.put( DigitRep.EIGHT.toString(),  "8");
        tmpMap.put( DigitRep.NINE.toString(),   "9");       
        VALID_DIGITS = Collections.unmodifiableMap(tmpMap);
    }

    /**
     * Private constructor to enforce flyweight/factory pattern.
     * 
     * @param blockRep
     */
    private Digit(String blockRep) {
        this.blockRep = blockRep;
    }

    /**
     * Flyweight factory method to create a Digit object from the "block"
     * representation of the digit.
     * @param blockRep The "block" representation of a digit.  Should look
     * something like:
     * " _ \n"
     * "|_|\n"
     * "|_|"
     * @return A flyweight Digit object representing the digit.
     */
    public static synchronized Digit getDigit(String blockRep) {
        Digit digit = digits.get(blockRep);
        if(digit == null) {
            digit = new Digit(blockRep);
            digits.put(blockRep, digit);
        }

        return digit;
    }

    /**
     * Determines whether or not the digit is valid.
     * @return true if the digit is valid, else false.
     */
    public boolean isValid() {
        return VALID_DIGITS.containsKey(blockRep);
    }

    /**
     * Accessor method to get the block representation of this digit.
     * 
     * @return
     */
    public String getBlockRep() {
        return blockRep;
    }

    @Override
    public String toString() {
        return VALID_DIGITS.containsKey(blockRep) ? VALID_DIGITS.get(blockRep) : "?";
    }
}

1
あまり知られていないが非常に有用なパターンの1つを+1する。
-MattDavey

2

オリジナルのGang of Fourのパターンのほとんどは現在も使用されていますが、本にはない他の現在人気のあるパターンがあります。

使用する言語のデザインパターンのリファレンスを検索します。より具体的で、特定の言語機能を使用して、パターンをより簡潔でエレガントな方法で実装する傾向があります。

デザインパターンに関する3つの優れたリソース:

「Head First Design Patterns」ブック -選択する言語はJavaですが、すべての言語に関連しています。 dofactory Design Patterns-コードを使用した優れた無料の.netデザインパターンの説明。 PluralSight-Design Patterns Library-これは有料ですが、リストに含めるにはあまりにも良いです。


1

ACEのような一般的なライブラリを使用する場合、使用すると思われる以上のものを使用することになります。Observer / Observableを広範囲に使用しています:-)


1

Builderを少なくとも1回使用しました(同じコンバータープロセスでHTMLまたはExcel出力を作成できます)。

私は頻繁にテンプレートメソッドを使用します(JDBC関連のタスク、または抽象Swingコントローラー用)。

かつて、多くの新機能をフォームベースのアプリケーションに開発する必要がありましたが、それは混乱でした。既存のものを状態パターンベースのソリューションにリファクタリングした後にのみ、私は進歩することができました。(まあ、ほとんど)。

また、コマンド(スイングアクション)を頻繁に使用し、オブザーバーも使用します。

Swingフォームの変更を検出するためにMemementoのようなソリューションを使用したことがあります。フォームは、以前の状態と比較した状態(equals())をシリアル化します。


1

私は彼らのほとんどが私のキャリアを通していると信じています。私が使用していないと確信しているのは、多重継承の大ファンではないため、本の多重継承で実装されているアダプタパターンだけです。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.