コマンドパターン はOCPを使用しますか?
コマンドパターンでは、呼び出し元は、実際にクラスを拡張することによってのみ拡張可能です。カスタムメソッドを追加する場合は、独自のサブクラスを作成するか、基本クラスのコンストラクターを変更することができますが、これは開閉の原則に違反しています。
私に疑問を投げかけるのは、OCPを使用するコマンドパターンかどうかです。
OCPのワンライナー定義は非常にいいですが、誤解を招く傾向があります。
元のボブマーティンの引用 OCPに関する記事 :
重要なプログラムを100%閉鎖できないことは明らかです。 ...一般に、モジュールがどの程度「閉じている」かに関係なく、閉じられていない変更が常に存在します。
(私は本当にあなたが論文全体を読むことをお勧めします ジョン・スキートの批評 )
したがって、基本的には、OCPは、可能な限り最小限のものを壊しながら、新しい機能を追加できるように適切な設計バランスを見つけることに関するものです。コードベースを拡張して完全に変更する必要はありません。
したがって、既存のコードを変更しながら、既存のインターフェイスとコントラクトを維持することが重要です。
コマンドパターンがOCPを解除するかどうかは、パターン自体よりも、どこでどのように使用されるかに基づいています。そして、あなたは使用のコンテキストを提供しなかったので、あなたの質問は本当に答えられません。
特定のパターンを使用する設計が、何らかの修正なしに新しい要件に対応できない場合に遭遇した場合、それはパターン(どちらでもかまいません)が不良であり、いくつかの優れた設計原則に違反していることを意味しません。
私たちのデザインがそのようなケースを適切に処理する準備ができていないことを意味するだけです。
いくつかのケースでははい。しかし、多くの場合、次のいずれかの兆候です。
設計を慎重に検討する必要がありますが、システムがどれほど順応性があるかに関係なく、いつか要件が変わったり、あいまいなドメインの知識によって、最も適切に設計されたシステムでさえ変更を余儀なくされたりします。
おそらく違います。他の優れた設計原則を損なうことなく、あらゆる方法で拡張できるシステムを設計することはできません。そのようなシステムは通常、パフォーマンスと(または)理解の容易さを犠牲にするためです。
thedailywtf で同様の過度に適応性のあるシステムについて読むのは罪悪感がありますが、最終的にはそれを維持したくありません。
より大きな設計について何も考慮せずにそのような変更が行われる場合は、おそらくそうです。しかし、このような変更を適切なコミットメントで適用し、 統合フェーズ 中にそれらをリファクタリングすると、エントロピーを抑えることができます。
So、 コマンドパターン は Open-Closed主義 に違反していますか?
いいえ。ほとんどの場合、システムの要件により、このパターンの特定の使用法は、私たちが望んでいたほどオープン/クローズではありません。
変化に対する開放性は戦略的な決定です。つまり、コードが開かれる変更に対して、開かれない変更を選択するのは設計者の責任です。また、多くの場合、1つの変更に対してデザインをオープンにすると、別の変更に対してデザインをオープンにすることが難しくなります。
コマンドパターンは、新しい動作の追加の変更に対してデザインをオープンにし、各動作は1つのコンテキストで使用できます(たとえば、動作の一般的なセットアップまたはティアダウン)。既存のコマンドの変更(デコレーターを適用できない場合)およびコマンドの設定方法の変更に対してはオープンではありません。
これらの変更に対して設計をオープンにする場合は、設計を拡張するか、設計を破棄して、新しい要件からやり直す必要があります。