戦略パターンを理解しようとして、自分自身に質問しています:コンテキストクラスは必須であるか、それともパターンの目的を損なうことなくそれを除外できますか?
さまざまな種類のファイルを読み取るためになんらかのスイッチが必要であるという印象を受けましたが、何かをハックして後でリファクタリングを処理したくありませんでした(もちろん、コードはリファクタリングできることは常にありますが、アイデアは:設計をできるだけスマートにするために、事前に...):
wikimedia から取得した画像
クライアントはストラテジーインターフェイスに直接委任できますか、それともコンテキストクラスについて理解できなかったことがありますか?
interface Reader {
// read information from file and fill data list field of Client
readFile();
}
class ExcelReader implements Reader{ /* */ }
class PdfReader implements Reader{ /* */}
class Client{
// strategic choice
Reader r;
// data list field
List<Data> data;
// Client Constructor
public Client(){
if(<file ends in .xls>)
r = new ExcelReader();
else
r = new PdfReader();
r.readFile();
}
}
したがって、上記のコンテキストクラスはありません。コードは戦略パターンに準拠していますか?
あなたの例では、readFile
を呼び出すコードはClientコンストラクターの一部です。 このメソッドは、探している「コンテキスト」です。戦略パターンには文字通り「コンテキストクラス」は必要ありません。コードの最初のバージョンでは、戦略オブジェクト(この場合は「リーダー」)がローカル変数にのみ存在する場合があります。特に呼び出される「戦略的メソッド」(「readFile」)が1つしかない場合。
ただし、コードベースが1つのバージョンから次のバージョンに成長する場合、呼び出される「戦略的」メソッドが増えることはまずありません。適用する戦略の決定と「戦略的メソッド」の実行は異なるタイミングで発生します。コード内のさまざまな場所。したがって、ロジックを1か所に維持するためにそれらをリファクタリングし始めます。これは、質問の図に似た実装に直接つながります。
もちろん。パターンは単なるガイドラインです。それでも、目前の問題に適切に適合させて適用する必要があります。個人的には、実行時に戦略を設定できることはほとんどありません。多くの場合、建設時に指定されるか、工場でスピンアップされます。
setStrategy
はプライベートであり、私のインジェクションは示されているパターンを使用していると主張することもできます。