GoFデザインパターン23個辿ることができたので, まとめ記事を書く.
とは言ってもすべて自分のTwitterの投稿の転載である.
Twitterの投稿だと後で見直すのがめんどくさそうだったのでブログでまとめて見れるようにした.
140文字という制約の元それぞれのデザインパターンを説明したため説明不足の部分もあるかもしれない. その場合, 自分で詳しく調べることをおすすめする.
Iteratorパターン
Iteratorパターン
— やぱったー (@yapatta_prog) 2020年4月29日
インターフェースのIteratorを何かしらの集合体のインターフェースAggregateが持っていて、Aggregateを実装したObjectの集合をiteratorを実装した具体iteratorがたどれるという感じかな
Adapterパターン
Adapterパターン
— やぱったー (@yapatta_prog) 2020年4月30日
元々存在しているクラスを新しいインターフェースに適応させるために使うイメージ。動作テストが通ってる既存クラスを修正して、再テストしないといけないのを防げる。
Templateパターン
Templateパターン
— やぱったー (@yapatta_prog) 2020年5月1日
スーパークラス(抽象クラス)で処理の枠組みを決めサブクラスで具体を実装する. スーパークラスのインスタンスを作ればロジックが共通だから, どのサブクラスか考えずに自動で処理を分けれて便利だよね
Factory Methodパターン
Factory Method
— やぱったー (@yapatta_prog) 2020年5月2日
Productとそれを生成するFactoryという抽象クラスを作成。実物のProductを作成するときそれぞれの具象クラスを用いる。インスタンスとその生成機をフレームワークと実際の肉付けに分ける感じか。
Singletonパターン
Singleton パターン
— やぱったー (@yapatta_prog) 2020年5月3日
インスタンスが一個しか存在しないことを保証したい。
クラスのインスタンスを一つしか作りたくないとき
クラスのコンストラクタをprivateにし、自前static変数にだけnewする。インスタンスにアクセスできるpublicなstatic関数を介してpublicなメンバ関数を実行できる。
Prototypeパターン
Prototypeパターン
— やぱったー (@yapatta_prog) 2020年5月6日
実験関係で更新遅れた
クラスを使わずにフレームワークを用いて雛形を管理して雛形をcloneしてインスタンスを作成する.雛形の種類が多すぎてクラスにまとめられない, クラスからインスタンス生成が難しい, 管理するフレームワークと生成するインスタンスを分けたいときに使うのかな.
Builderパターン
Builderパターン
— やぱったー (@yapatta_prog) 2020年5月7日
DirectorがBuilder役のインターフェースを使って文書を生成。ClientはDirectorを呼び出すだけで文書作成できるし、DirectorもBuilderの具象クラスを知らなくても文書構築ができる。(今回は異なるフォーマットにおける文書作成のために使った)
Abstract Factoryパターン
Abstract Factoryパターン
— やぱったー (@yapatta_prog) 2020年5月8日
AbstractProductとAbstractFactoryという対関係(Productは複数存在できる)、ConcreteProductとConcrete Factoryという対関係を持つ。Clientは具体実装を知らずにAbstractFactoryとAbstractProductだけを使って仕事できる。FactoryMethodとTemplateMethodを複雑にした感じか
Bridgeパターン
Bridgeパターン
— やぱったー (@yapatta_prog) 2020年5月9日
機能と実装のクラス階層にわける。機能のクラスでは実装のインターフェースを委譲してもらう。機能のクラス階層と実装のクラス階層を独立に拡張できるというメリットがある。
Strategyパターン
Strategyパターン
— やぱったー (@yapatta_prog) 2020年5月10日
アルゴリズム(Strategy)とアルゴリズムを利用する部分(Context)を分ける。Strategy役のインターフェースを作成し、ConcreteStrategyで実際の戦略を実装。StrategyはContextに委譲されてるだけであるため、Context内でアルゴリズムを容易に切り替えられる。
Compositeパターン
Compositeパターン
— やぱったー (@yapatta_prog) 2020年5月11日
容器(Composite)と中身(Leaf)をComponentとして同一視し再帰的な構造を作ってClientがその構造にアクセスできる。再帰的な構造のシチュエーション、例えばディレクトリとか箇条書きとか応用できる場面が多そう。
Decoratorパターン
Decoratorパターン
— やぱったー (@yapatta_prog) 2020年5月12日
ComponentやDecoratorをDecoratorが再帰的に包む(飾り枠と中身を同一視してるため)。透過的インターフェース(あるメソッドが隠されることなく他のクラスから見える)を用いることで包まれているものを変更せずに機能を追加できる。Decoratorには包む中身が委譲される。
Visitorパターン
Visitorパターン
— やぱったー (@yapatta_prog) 2020年5月16日
これマジでムズかった。データ構造と処理を分離。データ構造を探索するVisitorがデータ構造(element)に訪れるときelementが受け入れてあげる。elementとvisitorの行き来が複雑すぎて状態が分からなくなる...(初めてRedux学んだときを思い出した)
Chain of Responsibilityパターン
Chain of Responsibilityパターン
— やぱったー (@yapatta_prog) 2020年7月2日
Clientが委譲によってHandlerをゆるやかに繋げて、それぞれのHandlerはただ仕事を投げられたら処理するorできなかったら次のHandlerに投げるみたいな感じで仕事がたらい回される。中央集権的に誰がどの処理をするか明確に決める必要がない。
Facadeパターン
Facadeパターン
— やぱったー (@yapatta_prog) 2020年7月3日
システム内のクラスの役割、依存関係を考え、正しい順番でクラスを利用したインターフェース(API)を外部に提供する。インターフェースの量を少なくして外部との疎結合を狙う。これはWebバックエンドにおけるAPI設計の考えからか非常になじみやすかった。
Mediatorパターン
Mediatorパターン
— やぱったー (@yapatta_prog) 2020年7月4日
個々のColleagueはMediatorとだけ通信を行い、Mediatorが多数のColleague間の調整を行う。Colleagueは自身に状態変化があれば、Mediatorに伝え、指示に従うことを繰り返す。処理と状態を分けるイメージ。
GUIアプリケーションの表示のコントロールのロジックなどに使えそう。
Observerパターン
Observerパターン
— やぱったー (@yapatta_prog) 2020年7月8日
観察されるものSubjectがObserverを複数持ち、Subjectが更新されたときに, Observerのupdateがそれぞれ行われる(通知に近い). 実際はConcreteObserverとConcreteSubjectがインターフェースによって繋がれて実装される。またSubjectがObserverを複数登録するとき順序の影響を受けない
Mementoパターン
Mementoパターン
— やぱったー (@yapatta_prog) 2020年8月2日
カプセル化を破壊することなく状態の保存と復元を行う.CareTakerは状態のsnapshotを作成or復元するタイミングを指定, OriginatorがMementoを作成,or復元する.Mementoはwide-interfaceとnarrow-interfaceを持っており,wide~はOriginatorに開かれ,narrow~はCareTakerに開かれている.
Stateパターン
Stateパターン
— やぱったー (@yapatta_prog) 2020年8月14日
Stateごとにクラスを分離することで,設計者はあるState設計時には他のを考える必要がなく,またStateを変更するための条件分岐を書かずに済む.状態管理する者は他のConcreteStateを知らなければならない.Context役がConcreteStateを全て管理するようになるとMediatorパターンに近くなる?
Flyweightパターン
Flyweightパターン
— やぱったー (@yapatta_prog) 2020年8月17日
メモリ消費を少なくするためにintrinsicな情報を共有させ, なるべくインスタンスを生成しないようにする. もちろんインスタンスを共有するため, ある修正が複数箇所に影響することがある. インスタンスの管理者にSingletonを用いることもある. ついに残り3つになった.
Proxyパターン
Proxyパターン
— やぱったー (@yapatta_prog) 2020年8月18日
Proxyが代理人になってできる限り処理を肩代わりする. 実際にその機能が使われるときに初めて代理人ではなく本人が登場する. 本人の初期化に時間がかかりなるべく必要になるまで使いたくないときに便利. 遅延評価に似ている.
Commandパターン
Commandパターン
— やぱったー (@yapatta_prog) 2020年8月19日
命令をオブジェクトとして表現し, 命令と実行を分離する. これにより履歴を取ることや再実行が可能になる. 命令管理にstackなどのデータ構造を使うことで命令を複数管理できる. Compositeパターンを使って再帰的に命令を管理することも可能だ(ファイルとディレクトリみたいな).
Interpreterパターン
Interpreterパターン
— やぱったー (@yapatta_prog) 2020年8月24日
何らかのフォーマットの文章を, BNF等で定義されたルールに従い解析し処理を実現するのに役立つ. AbstractExpressionをConcreteExpressionが実装し, 構文規則に応じて再帰的に構文解析して構文木を組み立てることができる. 必ず終端となる表現が存在する.