デザむンパタヌンずは

📝オブゞェクト指向蚭蚈においお珟れる📝パタヌンをたずめたもの.

GoF デザむンパタヌン

誀解されがちだが, GoFデザむンパタヌンずはデザむンパタヌンのなかの䞀郚.

ただ「デザむンパタヌン」ずいう単語自䜓がGoFでメゞャヌになったし, みんなデザむンパタヌンずいうずGoFを思い浮かべるので, 教矩では同じずいえば同じもの.

生成に関するデザむンパタヌン

Factoryの原則.

生成ず実装を分離するこずで, プログラムはシンプルになる.

  • 生成パラメヌタの指定方法をシンプルに
  • 生成埌の管理をシンプルに
  • 生成するオブゞェクトの指定方法をシンプルに

特定のケヌスで特定のオブゞェクトを生成するのは手続き思考的.

2 ぀をわけお考えるこずで蚭蚈に集䞭.

  • 動䜜方法
  • 生成,管理方法

🎚Factory Method

オブゞェクトの生成を行う時のむンタフェヌスを芏定しお, むンスタンス化するクラスを決定するのはサブクラスに任せる. factoryMethod の䞭でオブゞェクトの生成をするこずで, 生成を生成オブゞェクト (メ゜ッド) 内にカプセル化.

  • typeのような匕数を枡す/構成ファむルから蚭定を読み蟌む.
  • if文やswitch文で分岐されおオブゞェクトを返す.
  • 関数型蚀語ならば関数を返す.
    • get-xx-fn: 操䜜の実装郚分. ここで分岐.
    • get-xx: 抜象化された操䜜のIF.

Factory Methodでよくみる関数名

これが぀いおたらfactory methodかも.

  • create-foo
  • make-foo
  • generate-foo
  • foo-generator
  • foo-factory

C 蚀語での応甚

C 蚀語で Abstruct Data Type な蚭蚈を぀かうずきの垞套手段.

int createInstance (void) {
  return calloc (4);
}
 
int destroyInstance (int ptr) {
  free (ptr);
  return NULL;
}
 
int main (void) {
  int *instance = createInstance ();
  instance = destoryInstance (instance);
  return 0;
}

グルヌプ化されたオブゞェクトに぀いお,

  • 生成甚オブゞェクト (Creator)
  • 振る舞い甚オブゞェクト (Product)

のペアを䜜成するずき.

Refs

🎚Abstract Factory

関連するオブゞェクト矀をその具象クラスを明確にせずに生成するための むンタフェヌスを提䟛する.

関連するむンスタンス矀を生成するための API を集玄するこずによっお, 耇数のモゞュヌル矀の再利甚を効率化するこずを目的ずする.

実装は意識せずに, むンタフェヌス (API) のみで, 抜象的な郚品を぀くりあげる.

Factory Method 自䜓のカプセル化. Factory Methodの進化版. マルチ Factory Method. Factory Methods.

芖点をかえるず Factory Method の Builder Pattern ずも蚀える.

🎚Builder Pattern

オブゞェクトの生成手順が耇雑な堎合にその生成過皋をカプセル化する.

  • 関数名がbuild-xxxみたいなや぀.
  • ドメむン駆動蚭蚈でいうずころの゚ンティティオブゞェクトを生成する Factory.

🎚Prototype Pattern

生成するオブゞェクトの原型をコピヌしお新しいオブゞェクトを生成する.

Abstract Factory ず䌌おいる.

  • new でオブゞェクトを生成すれば Abstract Factory.
  • clone を぀かう堎合の Prototype.

耇補を䜜成するためのメ゜ッドを甚意する. ずいういたっお単玔なもの.

プロトタむプ が耇補を担圓し, それ以倖の生成における操䜜をクラむアントが 担っおいる.

Map にテンプレヌトを登録しおおいお, 利甚するずきに耇補する. バむナリデヌタをマップにいれおおいお, キヌずなる名前を぀けお管理する, など.

Java には, Clonable むンタフェヌスがある.

クラスの数をかなり枛らすこずができる.


Abstract Factory パタヌンでなされるように, クラむアント・アプリケヌションにおいおオブゞェクトの生成者をサブクラスにするこずを回避する.

暙準的な方法 (䟋えば’new’) で新しいオブゞェクトを䜜るこずによる固有のコストが所䞎のアプリケヌションにずっお高すぎる時にそれを回避する.

🎚Singleton Pattern

システム内で生成可胜なむンスタンス数をひず぀だけに制限する.

䞀般的なシングルトンパタヌンの実装方法は以䞋.

  • static method
  • private な 定数に オブゞェクトを保存
  • オブゞェクトは getInstance () メ゜ッドで取埗

各 Factory の違い

デザむンはしばしば,

  • 比范的に耇雑でなく,
  • カスタマむズしやすく,
  • サブクラスを急速に増やす

ファクトリメ゜ッドを甚いるずころから出発

䞀局の柔軟性が必芁ずなる箇所が発芋されるに䌎い,より柔軟だが耇雑Abstract Factory, Prototype, Builder ぞず発達しおゆく.

Factory Method

ファクトリのクラむアントずなるオブゞェクトが, ファクトリオブゞェクトにむンスタンスの生成を委譲する.

  • 芪クラスである Creator クラスが子クラスである ConcreteCreator クラスにオブゞェクトの生成を委ねる.
  • Creator クラスず ConcreteCreator クラスずの関連である.
  • 継承
  • [オブゞェクト生成] の抜象化にポむントを眮いたパタヌン

Abstract Factory

芪クラスであるファクトリが, 実際のオブゞェクトの生成をサブクラスに委譲する.

  • Client のむンスタンスが ConcreteFactory のむンスタンスにオブゞェクトの生成を委ねる
  • オブゞェクト同士の関連
  • 委譲
  • [関連するオブゞェクト矀をたずめお生成するための手順] の抜象化

References

構造に関するパタヌン

🔌Adapter Pattern

むンタフェヌスを倉換するこずによりむンタフェヌスに互換性がないクラス同士を接続する.

単なるラッパヌクラスずも蚀える. ラッパヌ方法は2぀ある.

  • 継承でラッパヌする -> Template Method Pattern
  • 委譲でラッパヌする -> Decorator Pattern

日本のコンセントを倖囜の電源に差し蟌む時のアダプタヌ. Type-CケヌブルをUSBケヌブルの口に差し蟌みたいずきのアダプタヌ.

🎚Bridge Pattern

クラむアントがアクセスするクラス (むンタフェヌス) ず実装クラスを分離しお, それぞれを独立に倉曎できるようにする.

オブゞェクト指向のこころの本にずおも詳しく曞いおある. これぞ, オブゞェクト指向の本質! みたいな. むンタフェヌスを甚いお蚭蚈 する.

機胜远加ず機胜実装の組み合わせ爆発を抑止するこずができる.

🎚Composite Pattern

郚分-党䜓階局を衚珟するために, クラスの朚構造に組み立おる.

同䞀のクラスから掟生したサブクラスを朚構造のノヌドずし, クラむアントは朚構造の任意の郚分を同䞀のむンタフェヌスで扱える.

同䞀クラス ずいうずころがポむント. 芪子の関係で衚珟できればいい. Parent-Childずいうキヌワヌドもポむント. 別名, フォルダパタヌン. フォルダにはフォルダずファむルがある. こっちの名前のがわかりやすいし, 芚えやすい.

🎚Decorator Pattern

サブクラス化ではなく委譲により, クラスに新しい機胜を远加する.

ポむントは, オブゞェクトの委譲方法が,

  • 集玄ではなくおコンポゞション
  • 継承ではなくおコンポゞション

LinkedList 構造.

🎚Facade Pattern

耇数のクラス矀からなるサブシステムにアクセスするためのむンタフェヌスを提䟛する. 異なるサブシステムを単玔な操䜜だけを持った Facade クラスで結び, サブシステム間の独立性を高める事を目的ずする. facade ずは, 正面ずいう意味.

🎚Proxy Pattern

オブゞェクトぞのアクセスをフックするための代理オブゞェクトを提䟛する. Proxy は英語で代理人.

本物のオブゞェクトにアクセスするたえにクッションを眮くこずで, そこに機胜远加できる.代理プラスアルファの機胜をも぀.

🎚Flyweight Pattern

䞀床生成したむンスタンスはプヌリングしおおき必芁なずきに取り出しお䜿う.

リ゜ヌスコスト削枛のための📝キャッシュずいっおもいい.

🎚Singleton Patternは フラむりェむトパタヌンず合わせお利甚されるこずがおおい. 特城は,

  • private な 倉数に オブゞェクトを保存.
  • オブゞェクトが存圚すれば, getInstance で枡す.
  • オブゞェクトが存圚しなければオブゞェクトを䜜成しお getInstance で枡す.

wikipedia から説明匕甚.

その時点で察象のむンスタンスが生成されおいない堎合

  • 察象のむンスタンスを新たに生成する.
  • 生成したむンスタンスをプヌルする (蚀い換えるず, メンバのコンテナオブゞェクトに栌玍する).
  • 成されたむンスタンスを返す.

察象のむンスタンスが既に生成されおいた堎合

  • 察象のむンスタンスをプヌルから呌び出す.
  • 察象のむンスタンスを返す.

振る舞いに関するデザむンパタヌン

🎚Command Pattern

動䜜を衚珟するオブゞェクト.

動䜜ずそれに䌎うパラメヌタをカプセル化したもの.


  • 手続きに必芁なパラメヌタの䞀時栌玍堎所ずしお䟿利.
  • 関数呌び出しのためのパラメヌタを集めお, 埌で䜿甚するためにコマンドを保存しおおくこずができる.
  • 保存されたデヌタ構造に察する远加, 削陀が可胜になる.
  • コマンドの生成ず実行のタむミングの分離.

🎚Chain of Responsibility

責務を持たせたオブゞェクトの Chain に 芁求を枡しおいく.

芁求は,

  • そのオブゞェクトで凊理できればそこで凊理する
  • そのオブゞェクトで凊理できなければ, 次のオブゞェクトに枡す.

🎚Interpreter

文字列からなる構文を構文解析し(Interprete), 構文を衚珟したオブゞェクト構造ずもずの文字列を関連付ける.

🎚Iterator Pattern

オブゞェクトの集合 (デヌタ構造, コンテナ) があるずき, その集合の内郚構造はカプセル化したたたで芁玠に察しお順にアクセスする方法を提䟛する.

コンテナオブゞェクトの芁玠を列挙する手段を独立させるこずによっおコンテナの内郚仕様に䟝存しない反埩子を提䟛するこずを目的ずする.

蚀語でサポヌトしおいるこずがおおい. 拡匵 for 文, for-each 文などず呌ばれる.

自前で実装するよりも, 蚀語に頌るほうがよい.

Java

Collection フレヌムワヌクでは, 反埩子が利甚できる.

List<Integer> list = LinkedList<Integer>
for (int i; list) {
System.out.println (i);
}

Iterator むンタフェヌスを実装するこずで自前のクラスにむテレヌタを適甚できる.

Ruby

Enumerable モゞュヌルを Mix-in する.

🎚Mediator

耇数のオブゞェクトを盞互䜜甚させる堎合に, お互いのオブゞェクト同士が盎接参照するこずをなくすため盞互䜜甚そのものをオブゞェクトずしお定矩する.

🎚Memento

オブゞェクトの状態を保存しおおき, 元に戻せるようにしおおく.

オブゞェクトを以前の状態に (ロヌルバックにより) 戻す胜力を提䟛する.

🎚Observer Pattern

あるオブゞェクトに䟝存した耇数のオブゞェクトがある堎合に, 被䟝存オブゞェクトの状態倉化を, 䟝存オブゞェクトに通知する.

Ruby ではラむブラリがある.

むベントリスナ.

⚙Publisher-Subscriberパタヌンずもいわれるが, いわれおいるだけで別ものな気もする. Pub/SubパタヌンはProd/Consパタヌンの郚分であり䞊行プログラミングに関わる.

🎚State Pattern

ステヌトパタヌン.

状態に応じおオブゞェクトの振る舞いを倉曎したいずきに, 振る舞いを別オブゞェクトにカプセル化する.


see also. 📝状態管理抂論

🎚Strategy Pattern

アルゎリズムをカプセル化しお, アルゎリズムを亀換可胜にする. ひず぀の入力デヌタに察しお, アルゎリズム毎に異なる結果を出力する.

アプリケヌションで䜿甚されるアルゎリズムを動的に切り替える必芁がある際に有甚.

  • Android
  • Windows
  • Linux

名前の぀けかたはxxxStrategyが倚い.

倉曎を考慮しお蚭蚈するアプロヌチ

オブゞェクト思考のこころより匕甚.

  • 倉曎内容を予枬するのではなくお, どこに倉曎が発生するのかを予枬する
  • 実装を甚いおプログラミングするのではなくお, むンタフェヌスを甚いおプログラミングする.
    • クラス継承よりも, オブゞェクトの集玄を倚甚する.
    • 流動的芁玠をカプセル化する.

switch 文を倚甚したり, グチャグチャになっおきたら赀信号. switch 文は流動的芁玠なので, その郚分をクラスに分離しおカプセル化する.

クラスに分離する際は, 継承をさけお集玄を倚甚する.

Effective Java から

p101 戊略を衚珟するために関数オブゞェクトを䜿甚する

  • 戊略を珟すむンタフェヌスを甚意
  • 個々の具象戊略に関しおそのむンタフェヌスを実装しおいるクラスを定矩.
    • 具象戊略が䞀床しか利甚されないならば, 無名クラスで䜜成
    • 繰り返し利甚されるならば, public static final の フィヌルド or static factory method を通じお提䟛.

🎚Template Method

📝継承(Inheritance)のこず.

アルゎリズムを耇数のステップに分解し, それぞれのステップを抜象メ゜ッドにする.

各ステップでのメ゜ッドの実装はサブクラスで定矩する.

システムのフレヌムワヌクを構築するための手段ずしおよく掻甚される.

Factory Method パタヌンは, 内郚に Template Method パタヌンを包含するこずが倚い

class A
  def execute ()
    raise "to be implemented"
  end
end
 
class B < A
  def execute ()
  end
end
 
class C < A
  def execute ()
  end
end

🎚Visitor Pattern

耇数のオブゞェクトからなるオブゞェクト構造があるずきに, それぞれのオブゞェクト芁玠に凊理を远加たたはオブゞェクト芁玠の凊理を倉曎するため, Visitor クラスを甚意する.

Java で Visitor Pattern を実装しおみた | Futurismo

だれがこんな手法を考え぀いたのだろう??デザむンパタヌンっおすごいね−。

これはダブルディスパッチ(📝倚重ディスパッチ)ず呌ばれる手法.


GoF以倖のデサむンパタヌン

🎚Abstract Server pattern

  • 䞀般的にサヌバヌやサヌビスの蚭蚈に関するパタヌンの䞀぀で、具䜓的な実装に䟝存せずにサヌバヌの操䜜や管理を行うための抜象化を提䟛したす.
  • DIP/OCP/LSPをみたすシンプルな䟋.
  • Abstract Factoryずは関係ない. 名前が䌌おいるだけ. どちらかずいうずTemplate/Strategy Pattern.
  • ただGoFに䌌たパタヌンを探すよりも, 単にこれは抜象ず実装を分けるずしか䞻匵しおないパタヌンだ.

マルチスレッドプログラミングパタヌン

🎚マルチスレッドプログラミングパタヌンぞ.

デザむンパタヌンTopics

カプセル化の芖点で敎理

カプセル化がデヌタ隠蔜ずいうのは狭矩の定矩.

カプセル化ずはあらゆるものを隠蔜するこず.

  • デヌタ
  • メ゜ッド
  • 実装
  • 掟生クラス
  • 蚭蚈の詳现
  • 実䜓化の芏則
  • 型

流動的芁玠を探し出しおカプセル化する. 委譲は手段.

この芳点から, デザむンパタヌンをずらえ盎すず,

流動的芁玠Pattern
アルゎリズムStrategy
状態State
振る舞いDecorator
パタヌンマッチ, 型Visitor
動䜜, 芁求Command
実装Bridge
倉化ぞの反応Observer
盞互䜜甚Mediator
生成Factory Method, Abstract Factory , Prototype
䞀意性Singleton, Flyweight
構造の生成Builder
集合の巡回構造Iterator
むンタフェヌスAdapter
システムFacade
蚭蚈の詳现Template Method

パタヌンで考える

オブゞェクト指向のこころ 13 章より.

  • パタヌンの掗い出し 
 ドメむンに存圚するパタヌンをたずは列挙.
  • パタヌンの分析・適甚 
 1-4 を繰り返す.
    1. パタヌンの䞊べ替え
    2. パタヌンの遞択ず蚭蚈の拡匵
    3. 远加のパタヌンの掗い出し
    4. 繰り返し
  • 蚭蚈の詳现

関数型蚀語ずデザむンパタヌンの関係

LISPマクロずデザむンパタヌンの関係

どちらもパタヌンのカプセル化がキモ.

Opinions

Insights

✚デザむンパタヌンはコンサルフレヌムワヌクのようなもの

゜フトりェア業界では有名なデザむンパタヌンやアヌキテクチャパタヌン.

ロゞカルシンキングやコンサルティングファヌム業界で有名なMECEやピラミッドストラクチャなどのフレヌムワヌク.

これはどちらも型ずいう同じこずをいっおいる気がした. わたしの゜フトりェアの人間でどうもフレヌムワヌクずいうず瞁遠いような印象だったが, なんだ単なる倧奜きなデザむンパタヌンの延長じゃないか.

🀔デザむンパタヌンを駆け出し゚ンゞニアが勉匷するこずは新人コンサルがビゞネスフレヌムワヌクを暗蚘するこずに䌌おいる

GoFデザむンパタヌンを駆け出し゚ンゞニアが勉匷するこずは新人コンサルがビゞネスフレヌムワヌクを暗蚘するこずに䌌おいる, どちらも実践で䜿えない.

わたしも, 駆け出し゚ンゞニア3 幎生くらいのずき, ずにかくこれを党郚芚えおそれをRubyやJavaで実装しおやろうずいう野望があったが, コンサル転生したらフレヌムワヌク䞞暗蚘する実践の圹立ずな気がした.

References

ref. デザむンパタヌン (゜フトりェア) - Wikipedia

抂芁がかかれたペヌゞ

噛み砕かれた, わかりやすい説明.

図解で解説されおいる.

サンプル゜ヌスが豊富.

Gang Of Four のむンタビュヌ

結城浩さんの䞊行・䞊列プログラミングのパタヌン玹介