JavaのコアライブラリのGoFデザインパターンの例


672

GoF Javaデザインパターンを学習しています。実際の例をいくつか見てみたいと思います。Javaのコアライブラリのこれらのデザインパターンの良い例は何ですか?

回答:


3229

ウィキペディアで多くのデザインパターンの概要を見つけることができます。また、GoFによってどのパターンが言及されているかも言及しています。ここではそれらをまとめて、Java SE APIとJava EE APIの両方で見られるパターン実装をできるだけ多く割り当てようとします。


創造的なパターン

抽象ファクトリー (ファクトリー自体を返す作成メソッドによって認識可能であり、ファクトリーを使用して、別の抽象/インターフェースタイプを作成できます)

ビルダー (インスタンス自体を返す作成メソッドで認識可能)

ファクトリー・メソッド (抽象/インターフェース・タイプの実装を返す作成メソッドによって認識可能)

プロトタイプ (同じプロパティを持つ自身の異なるインスタンスを返す作成メソッドによって認識可能)

シングルトン (毎回同じインスタンス(通常はそれ自体)を返す作成メソッドで認識可能)


構造パターン

アダプター 異なる抽象/インターフェース型のインスタンスを取り、指定されたインスタンスを装飾/オーバーライドする独自/別の抽象/インターフェース型の実装を返す作成メソッドによって認識可能)

ブリッジ 異なる抽象/インターフェース型のインスタンスを取り、指定されたインスタンスを委任/使用する独自の抽象/インターフェース型の実装を返す作成メソッドによって認識可能)

  • まだ何も思い浮かびません。架空の例はnew LinkedHashMap(LinkedHashSet<K>, List<V>)、アイテムのクローンを作成せずにそれらを使用する変更不可能なリンクマップを返します。java.util.Collections#newSetFromMap()およびsingletonXXX()方法は、しかし近づきます。

コンポジット 同じ抽象/インターフェース型のインスタンスをツリー構造に取り込む動作メソッドによって認識可能)

デコレーター (追加の動作を追加する同じ抽象/インターフェース型のインスタンスをとる作成メソッドによって認識可能)

ファサード (内部で異なる独立した抽象/インターフェースタイプのインスタンスを使用する動作メソッドによって認識可能)

Flyweight (キャッシュされたインスタンスを返す作成メソッドで認識可能、少し「マルチトン」のアイデア)

プロキシ (特定の抽象/インターフェースタイプの異なる実装を委任/使用する特定の抽象/インターフェースタイプの実装を返す作成メソッドで認識可能)


行動パターン

責任の連鎖 (キュー内の同じ抽象/インターフェイス型の別の実装で同じメソッドを(間接的に)呼び出す動作メソッドによって認識可能)

コマンド (作成時にコマンド実装によってカプセル化された異なる抽象/インターフェース型の実装のメソッドを呼び出す抽象/インターフェース型の動作メソッドによって認識可能)

インタープリター (指定されたインスタンス/タイプの構造的に異なるインスタンス/タイプを返す動作メソッドによって認識可能。構文解析/フォーマットはパターンの一部ではないことに注意してください。パターンとその適用方法を決定します)

イテレータ (キューから異なるタイプのインスタンスを順次返す動作メソッドによって認識可能)

メディエーター (指定されたインスタンスを委任/使用する(通常はコマンドパターンを使用する)異なる抽象/インターフェイスタイプのインスタンスをとる動作メソッドによって認識可能)

Memento (インスタンス全体の状態を内部的に変更する動作メソッドによって認識可能)

オブザーバー(またはパブリッシュ/サブスクライブ) (自分の状態に応じて、別の抽象/インターフェースタイプのインスタンスでメソッドを呼び出す動作メソッドによって認識可能)

状態 (外部で制御できるインスタンスの状態に応じて動作を変更する動作メソッドによって認識可能)

戦略 (戦略の実装にメソッド引数として渡された、異なる抽象/インターフェース型の実装のメソッドを呼び出す抽象/インターフェース型の動作メソッドによって認識可能)

テンプレートメソッド (抽象型によって定義された「デフォルト」の動作をすでに持っている動作メソッドによって認識可能)

訪問者 (2つの異なる抽象/インターフェースタイプによって認識可能であり、他の抽象/インターフェースタイプを取るメソッドが定義されています。一方は実際に他方のメソッドを呼び出し、もう一方はそのメソッドに対して望ましい戦略を実行します)


23
印象的.. :) +1。javax.lang.model.element訪問者を定義しています。)私はかなり確実かどうかじゃないdoXXXdoFilter「戦略」です。
Bozho

16
上記のビルダー、たとえばStrinbgBuilderはすべてBuilder-Patternの例ではありません。ただし、それらをビルダーと見なすことはよくある間違いです(そのため、実際に^ _ ^を非難する必要はありません)
Angel O'Sphere

77
@BalusC、私はあなたに尋ねる質問があります。JavaとJSFの完全なソースコードを読みましたか?
Tapas Bose

20
@Tapas:私はすべてを読んだわけではなく、必要な部分だけを読んだり、「彼ら」がそれをどのようにしたのかについて興味があった。
BalusC 2013年

7
「ファクトリー・メソッド」の例のほとんどは、GoFパターンではない「静的ファクトリー」の例です。正しくありません。
リングベアラー

107
  1. スイング全体のオブザーバーパターン(ObservableObserver
  2. MVCもスイング
  3. アダプタパターン:InputStreamReaderのとのOutputStreamWriter注:ContainerAdapterComponentAdapterFocusAdapterKeyAdapterMouseAdapterありませんアダプター。それらは実際にはNullオブジェクトです。Sunによる不適切なネーミングの選択。
  4. デコレータパターン(BufferedInputStreamなどの他のストリームを装飾できますFilterInputStream
  5. AWTツールキットとSwingのプラグイン可能なLook&FeelクラスのAbstractFactoryパターン
  6. java.lang.Runtime#getRuntime() シングルトンです
  7. ButtonGroup メディエーターパターン
  8. ActionAbstractAction異なるコードで同じコードを実行するために使用できます->コマンドパターン
  9. Flyweightパターン用のJTableのインターンされた文字列またはCellRender(さまざまなプールについても考えてください-スレッドプール、接続プール、EJBオブジェクトプール-Flyweightは実際には共有リソースの管理についてです)
  10. Java 1.0イベントモデルは、サーブレットフィルタと同様に、責任の連鎖の例です。
  11. Collections Frameworkのイテレーターパターン
  12. AWT / Swingのネストされたコンテナーは複合パターンを使用します
  13. AWT / Swingのレイアウトマネージャーは戦略の例です

そして私は推測するより多く


1
MouseAdapterのヒントをありがとう。:私はこのexaplanation見つけstackoverflow.com/questions/9244185/...
リンカーン

Swingは大まかに MVC に基づいていることに注意してください。ビューとコントローラーを1つのクラスにまとめました。
Matthias Braun

51
  1. Flyweightは、Byte、Short、Integer、Long、Stringの一部の値で使用されます。
  2. ファサードは多くの場所で使用されていますが、最も明白なのはスクリプトインターフェイスです。
  3. シングルトン -java.lang.Runtimeが思い浮かびます。
  4. 抽象ファクトリ -スクリプトとJDBC APIも。
  5. コマンド -TextComponentのUndo / Redo。
  6. インタープリター -RegEx(java.util.regex。)およびSQL(java.sql。)API。
  7. プロトタイプ -これが重要かどうかは100%わかりませんがclone()、この目的にはメソッドを使用できると思います。

1
Flyweightパターンについて:java.awtjava.swingパッケージのレイアウトマネージャーが異なる場合があります。実際、これらはほぼ同じ組み込み属性を共有し、外部属性はUIフォームでレイアウトする異なるUIコンポーネントです。
ヴィタリー

@NawaManあなたは5. Comand TextComponentのUndo / Redoを言った。コマンドではなく記念品だと思います。またはおそらく両方です。
Stimpson Cat

関連質問-stackoverflow.com/questions/61284856/…で私を助けていただけませんか。この簡単な例ではコマンドパターンを使用しましたが、それが私の問題を解決する正しい方法であるかどうかはわかりません。
Tom Joe

42

RMIはプロキシに基づいています。

GoFの23のパターンのほとんどを引用できるはずです。

  1. 抽象ファクトリー:ドライバーが登録されると、java.sqlインターフェースはすべて、JDBC JARから具体的な実装を取得します。
  2. ビルダー:java.lang.StringBuilder。
  3. ファクトリー・メソッド:XMLファクトリーなど。
  4. プロトタイプ:多分clone()ですが、それを購入するかどうかはわかりません。
  5. シングルトン:java.lang.System
  6. アダプタ:WindowAdapterなどのjava.awt.eventのアダプタクラス。
  7. ブリッジ:java.utilのコレクションクラス。ArrayListによって実装されるリスト。
  8. コンポジット:java.awt。java.awt.Component + java.awt.Container
  9. デコレーター:java.ioパッケージ全体。
  10. ファサード:ExternalContextは、Cookie、セッションスコープ、および同様の操作を実行するためのファサードとして動作します。
  11. フライウェイト:整数、文字など
  12. プロキシ:java.rmiパッケージ
  13. 責任の連鎖:サーブレットフィルター
  14. コマンド:Swingメニュー項目
  15. インタプリタ:JDKでは直接使用できませんが、JavaCCでは確かにこれを使用します。
  16. イテレーター:java.util.Iteratorインターフェース。それより明確にすることはできません。
  17. メディエーター:JMS?
  18. メメント:
  19. オブザーバー:java.util.Observer/Observable(ただし、正しく行われていません)
  20. 状態:
  21. 戦略:
  22. テンプレート:
  23. ビジター:

23のうち10のJavaの例を考えることはできませんが、明日はもっとうまくできるかどうかを確認します。それが編集の目的です。


28

Abstract Factoryパターンはさまざまな場所で使用されています。例えば、DatagramSocketImplFactoryPreferencesFactory。さらに多くのものがあり、Javadocで名前に「Factory」という単語が含まれているインターフェースを検索します。

また、Factoryパターンのインスタンスもかなりあります。


22

私はこれでちょっと壊れた時計ですが、Java XML APIはFactoryをよく使用します。これを見てください:

Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(source);
String title = XPathFactory.newInstance().newXPath().evaluate("//title", doc);

...などなど。

さらに、さまざまなバッファー(StringBuffer、ByteBuffer、StringBuilder)はビルダーを使用します。


21

java.util.Collection#Iteratorは、ファクトリメソッドの良い例です。使用するコレクションの具象サブクラスに応じて、イテレーター実装が作成されます。Factoryスーパークラス(コレクション)と作成されたイテレーターの両方がインターフェースであるため、AbstractFactoryと混同される場合があります。受け入れ答え(BalusC)でAbstractFactoryの例のほとんどは、の例である工場、オリジナルのGoFパターンの一部ではないファクトリメソッドの簡易版。Facoryでは、Factoryクラス階層が縮小され、ファクトリーは他の手段を使用して、返される製品を選択します。

  • 抽象ファクトリー

抽象ファクトリには複数のファクトリメソッドがあり、それぞれが異なる製品を作成します。1つの工場で生産された製品は、一緒に使用することを目的としています(プリンターとカートリッジは同じ(抽象的な)工場のものを使用することをお勧めします)。上記の回答で述べたように、AWT GUIコンポーネントのファミリーは、プラットフォームごとに異なります(ただし、その実装はGofで説明されている構造とは異なります)。

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