Open13

デザインパターン

kondokondo

第7章 Iterator

概要

別のオブジェクトを生成する"スタイル"を外部イテレータと、そのオブジェクト内で実行する内部イテレータに区分できる。Rubyの場合は、eachメソッドにブロックを渡すといった内部イテレータが充実している。よって基本的には内部イテレータ、そして便利なEnumerableモジュールを使用するのが良い。外部イテレータが必要になるケースとしては、2つのオブジェクト、例えば配列を1つにマージするといったものが考えられる。

コメント

Rubyを書く上ではそれほど意識せずともイテレータパターンを使用しているように思えた。

kondokondo

第5章 Observer

概要

ニュースを持っているクラスをサブジェクト(Subject)、ニュースを得ることに関心のあるオブジェクトをオブザーバー(Observer)と呼ぶ。オブザーバーをサブジェクトに登録して使用する。例えば、従業員(オブザーバー)が昇給(ニュース)したら人事部に通知する。
Observerパターンの注意点としては、オブジェクトの更新頻度、通知のタイミングなどがある。

コメント

RailsではActiveRecordのコールバックがよく使用されている。普段の業務でもこのコールバックは頻繁に利用されているが、下記の記事の通りデータの更新意図が不明なため個人的には懐疑的。ドメインイベントを通知する形が良いのではないか、と思っているので今後試してみたい。

https://techracho.bpsinc.jp/hachi8833/2022_09_27/59155

kondokondo

第6章 Composite

ユースケース

すべてのオブジェクトの共通のインターフェースまたは基底クラスであるコンポーネント(Component)、最小単位で配下に子を持たないリーフ(Leaf)、Leafを集めた配列を持つコンポジット(Composite)で構成する。ユースケースとしては、例えばケーキを造るには様々な工程がある。「小麦粉を入れる」・「生地を焼く」といったリーフを集めたコンポジットを作成する。リーフの構成はコンポーネントで定義される。コンポジットに対して、各工程の時間の合計値を出すメソッドを定義することが可能。

コメント

木構造を扱う場面で活用できそうだ。例えば会社の部署はいくつもの階層になっていることが多い。配下の部署の合計人数を出す、といった処理などは有り得そうである。

kondokondo

第1章 よりプログラムとパターン

概要

継承はリスコフの置換原則を満たすべき場合においてのみ用いるべきである。単に処理の共通化などといった理由で継承を使用するのはアンチパターン。小クラスでオーバーライドする、条件分岐が発生するみたいな実装はリスコフの置換原則に反していることが多いはず(多分)。
集約は別オブジェクトを作成すること。車やバイクにはエンジンという集約を見出すことができる。エンジンオブジェクトを作成することで、処理を委譲することが可能。

コメント

Golangには継承がなく、interfaceを用いる。Rubyにはinterfaceがないので、モジュールをincludeすることで代用できそう。
https://zenn.dev/miya_tech/articles/83bafc09eaffbd

kondokondo

第4章 Strategy

概要

各ストラテジ(Strategy)は正確に同じインターフェースを持つ。ストラテジの利用者はコンテキスト(context)と呼ぶ。ストラテジオブジェクトを生成してそれを初期化の引数に渡して、コンテキストオブジェクトを生成する。コンテキストオブジェクトに対して命令を与えれば、ストラテジオブジェクトに定義された処理が実行される。
Rubyではブロックを用いることで、ストラテジクラスの定義を省略することが可能である。

コメント

ダックタイプを感じた時に活用できそうだ。コンテキストにストラテジオブジェクトからなる配列を用意して、順番に配列からストラテジを取り出して処理させるケースなどは便利そうだ。Deviseだと各認証の仕組みをStrategyで提供している。

kondokondo

第8章 Command

概要

何を行うかの決定とそれの実行を分離する。

コメント

なんというかこれまでの"焼き直し"に近い。こうなってくると「デザインパターンは無意味」みたいな風潮も理解できる気がした。

以下の、Strategy、State、Commandは、使われる状況は違いますが、単に切り替わるクラスが戦略なのか、状態なのか、コマンドなのかの違いだけです。これはクラス構成上のテクニックというよりは、何をオブジェクトとして取り出すかという指針に過ぎません。

デザインパターンを読み解く

kondokondo

第9章 Adapter

概要

クライアントがあるクラスへのインターフェイスを持っていないとする。その場合に、インターフェイスを仲介するAdapterクラスを作成して、クライアントとAdapteeクラスを繋げる。クライアントはAdapterの存在を意識することはない。

コメント

こういう場合、オープンクラスや偶にインスタンスの変更で対応することが多かったように思う。Adapterを使用すれば影響範囲を小さくできる。オープンクラスは強力すぎるし、インスタンスの変更も複数のインスタンスにまたがる変更の場合は上手く行かない。大量のモンキーパッチから脱却できるだろうか。

kondokondo

第10章 Proxy

概要

本物のオブジェクトであるサブジェクト(subject)を代理するプロキシー(proxy)オブジェクトを作成する。クライアントから見るとプロキシーはサブジェクトと同じインターフェイスを持つ。プロキシーの目的は、関心の分離にある。バリデーションを挟んだり、ネットワークの複雑さを隠蔽したり。。またプロキシー内でサブジェクトを生成することで、オブジェクトの生成を遅延させ、コストを減らすことができる。バリデーションで引っかかれば、サブジェクトを生成する必要はない。

コメント

Proxyという名前はWardenで見たことがあった。同じインターフェイスを持つクラスを作成して、何か処理を挟む。それは関心の分離のためである。まあこれくらいで何となく覚えておきたい。

kondokondo

第11章 Decorator

###概要
デコレータ(decorator)クラスは、コンポーネント(Component)の参照を持っている。実行時に必要な機能を組み立てることができる。

コメント

業務だとdraperというgemを使ってデコレータを取り入れている。表示に関わるロジックをmodelから引きはがすことができるので便利。

kondokondo

第12章

概要

シングルトンクラスのインスタンスはそのクラス唯一のインスタンスである。クラス変数を利用して、newクラスメソッドをプライベートにすることで作成できる。

コメント

設定値とか、実行時に唯一であることを担保したい時に利用できそう。

kondokondo

第13章 Factory

概要

クラスの選択の決定をサブクラスに押し付ける。Pondクラスに対するDuchPondやFrogPond。また矛盾のないオブジェクトの組み合わせを作るためのオブジェクトをアブストラクトファクトリと呼ぶ。カエルとスレイン、トラと樹木のペアの組み合わせ。

コメント

ユースケースや目的がイメージし辛い。例にあるように池のようなクラスが複数存在する場合とかだろうか。他には下記のサイトの、ピザ屋にはシカゴピザ屋、ニューヨークビザ屋があるという例が分かりやすかった。
https://supersoftware.jp/tech/20230509/18753/

kondokondo

第14章 Builder

概要

オブジェクトの構築のロジックを別クラスでカプセル化するもの。

コメント

正直あまり特筆することはない。。