2017-12-10 14 views
0

私は以下のようなファクトリメソッドを持っています。これを設計するより良い方法は、あなたが動的に基づいてインスタンスを作成することができますので、私は概要異なるコンストラクタ引数を持つ型のファクトリまたはファクトリメソッド

public IPolicy CreatePolicy(Context context) 
{ 
    IPolicy policy = default(IPolicy); 
    ISettings settings = _settings.Get(context); 
    Policy policyType = (Policy) Enum.Parse(typeof(Policy), settings.Policy); 
    switch (policyType) 
    { 
     case Policy.Policy1: 
      policy = new Policy1(_policy1Service, _logHandler); 
      break; 
     case Policy.Policy2: 
      policy = new Policy2(_policy2Service, _logHandler); 
      break; 
     case Policy.Policy3: 
      policy = new Policy3(_policy1Service, _policy2Service, _logHandler); 
      break; 
    } 
    return policy; 
} 
+0

あなたは 'IPolicy'の汎用メソッドの作成について考えましたか? – MethodMan

+0

あなたのコードはOCPを尊重していると主張できます。 'CreatePolicy'は閉じています(新しいポリシーを追加してもクライアントを呼び出すクライアントは変更する必要はありません)が、スイッチの隠された情報の拡張には開いています。 OCPはあなたが*バリエーションを保護していると言います。 – Fuhrmanator

答えて

0

が列挙リテラルは正確にあなたのクラス名と同じであるはずswitchステートメントを使用して開いたクローズドの原則を達成する必要はありませんありますコンストラクタのパラメータを渡す

public static IPolicy CreatePolicy(Policy policy) 
{ 
    //Change this if the namespace of your classes differs 
    string ns = typeof(Policy).Namespace; 

    string typeName = ns + "." + policy.ToString(); 

    return (IPolicy)Activator.CreateInstance(Type.GetType(typeName)); 
} 

のようなリテラルの列挙型は、これは非常に珍しいですので、単純に

return (IPolicy)Activator.CreateInstance(Type.GetType(typeName), 
    _policy1Service, _logHandler); 

のようにそれらを追加することでも可能ですInitialize(...)メソッドをIPolicyに追加して、空のコンストラクタを許可するためにこれらのパラメータを渡すことを考えてください。

関連する問題