さらに読む:戦略パターン; テンプレート メソッド パターン; 制御の反転(IoC)。
これを行う 1 つの方法は、顧客固有の機能をリッスンする必要があるロジックを抽出し、実装をコードに焼き付けるのではなく挿入することです。たとえば、次のインターフェイスを使用します。
public int GetAge(Person p)
{
return p.Age;
}
顧客が年齢について嘘をつきたがっているので、すべての年齢に 1 を足すように頼まれました。
public int GetAge(Person p)
{
var age = p.Age;
// Imagine all this exists...
if (CustomerContext.CurrentCustomer == Customer.One)
{
age++;
}
return age;
}
アイデアは、年齢の後処理を抽出することです。
public int GetAge(Person p, IAgePostProcessor ageProcessor)
{
var age = p.Age;
return ageProcessor.Process(age);
}
public interface IAgePostProcessor
{
int Process(int age);
}
次に、これ以外に、自分がどのような顧客のコンテキストにいるかを知っているときに、起動時に一度戦略を構成することを決定できます.
その 1 人の顧客には年齢を +1 する実装を提供し、他のすべての顧客には何もしないパススルー実装を提供します。
他の DI/IoC フレームワーク (Ninject、Castle Windsor、StructureMap) を利用して、このような配管を支援できます。
または、「インターフェース」は単に次のようにすることもできます
Func<int, int>
。
public int GetAge(Person p, Func<int, int> postProcessAge)
{
if (postProcessAge == null)
postProcessAge = a => a; // Do nothing.
return postProcessAge(p.Age);
}
これにより、依存関係がこのメソッドの外に移動し、別の場所でロジックに関する決定を行うことができます。おそらく、起動時に一度集中化されます。
すべてのアプローチの利点は、各クライアントの受け入れ基準が満たされていることを証明するために使用される場所に関係なく、顧客固有の実装をテストできることです。