私が長年携わってきたプロジェクトでは、非常に役立つことが証明されているデザイン パターンを徐々に進化させてきました。私は時々それで少し福音的にならなければならないと感じますが、それが誰かの古い帽子の私のバージョンであることがわかったら、少し恥ずかしいです. 私は無駄にデザインパターンを掘り下げましたが、それについて話している人に出くわしたことはありませんが、私の検索は網羅的ではありませんでした.
コアとなるアイデアは、一連の定義オブジェクトを管理するブローカー オブジェクトを持つことです。各定義オブジェクトは、いくつかの複雑なプロパティの可能な値を構成します。例として、すべて EngineType を持つ Car、Plane、および Generator クラスがあるとします。Car は独自の EngineType オブジェクトを保存しません。車が持つエンジンの種類を示す何らかの種類の参照キー (整数または文字列 ID など) を保存します。たとえば、WankelEngine などの EngineType のプロパティまたは動作を調べたい場合は、EngineTypeBroker シングルトン オブジェクトに WankelEngine の定義オブジェクトを要求し、それに参照キーを渡します。このオブジェクトは、EngineTypes について知っておくべき興味深いことをすべてカプセル化します。単にプロパティ リストである可能性がありますが、動作が読み込まれる可能性もあります。
したがって、それが促進しているのは一種の共有された疎結合の集約であり、多くの車が WankelEngine を持っている可能性がありますが、WankelEngine 定義オブジェクトは 1 つしかありません (そして、EngineTypeBroker はそのオブジェクトを置き換えることができ、疎結合を強化された実行時のモーフィズムに活用します)。
私が使用するこのパターンのいくつかの要素 (引き続き EngineType を例として使用します):
- 指定された値が EngineType の有効な参照キーであるかどうかを判断するための IsEngineType(x) 関数と、参照キーに対応する EngineType 定義オブジェクトを取得するための EngineType(x) 関数が常に存在します。
- 特定の EngineType に対して常に複数の形式の参照キーを許可します。常に少なくとも文字列名と定義オブジェクト自体、多くの場合は整数 ID、そして場合によっては EngineType を集約するオブジェクト タイプを許可します。これはデバッグに役立ち、コードをより柔軟にし、私の特定の状況では、古い慣行と比較して多くの下位互換性の問題を緩和します. (このプロジェクトのコンテキストでは、人々がこれをすべて行うために使用する通常の方法は、EngineType が持つ可能性のある各プロパティのハッシュを定義し、参照キーでプロパティを検索することでした。)
- 通常、各定義インスタンスは、その定義タイプの汎用クラスのサブクラスです (つまり、WankelEngine は EngineType を継承します)。定義オブジェクトのクラス ファイルは、/Def/EngineType のようなディレクトリに保持されます (つまり、WankelEngine のクラスは /Def/EngineType/WankelEngine になります)。そのため、関連する定義はグループ化され、クラス ファイルは EngineType の構成ファイルに似ていますが、コードを定義する機能があります (通常、構成ファイルにはありません)。
いくつかの自明なサンプル疑似コード:
class Car {
attribute Name;
attribute EngineTypeCode;
object GetEngineTypeDef() {
return EngineTypeBroker->EngineType(this->GetEngineTypeCode());
}
string GetDescription() {
object def = this->GetEngineTypeDef();
return "I am a car called " . this->GetName() . ", whose " .
def->GetEngineTypeName() . " engine can run at " .
def->GetEngineTypeMaxRPM() . " RPM!";
}
}
それで、これに名前はありますか?