2017-11-26 11 views
1

私は多くの行動を取っています。すべてのアクションは、すべてのアクションで渡されたオブジェクト/コンテキストで動作します。パターンStrategy/Policyを使いたいです。ここで戦略 - インターフェイスタイプ別に自動的に登録

はKotlinの例である:

interface Action { 
    val name: String 

    fun run(ctx: Context) 
} 

class Multiply: Action { 

    override name = "MULTIPLY" 

    override fun run(ctx: Context) { 
     writeToDb(ctx.id, ctx.number * 2) 
    } 
} 

class Substract 

class SendNotification 

etc... 

だから私は、起動時にすべての戦略を登録したいです。また、列挙型のような構造から戦略を選択します。

val action = selectAwaitingAction() 
val ctx = selectCtxById(action.transaction_id) 
perfromAction(ctx, actions.getByName(action.name)) 

fun performAction(ctx Context, action: Action) { 
    action.run(ctx) 
} 

私の質問は、インターフェイスタイプによる登録戦略です。

+0

ことが可能であることを確認してください。質問とは何ですか?それをやってください。 – Vadim

+0

@ Vadim、私はこれを実装に固執しています。私はどのようにすべての戦略を登録することができますか?インターフェイス – Sonique

+1

あなたが投稿したコードはJavaではありません。どの言語をお探しですか? – Bedla

答えて

0

注:これは完全な例です。インタフェースタイプによる自動登録のみをお探しの場合は、最後の部分にスクロールしてください。

ストラテジーデザインパターンは、ファンクションテーブルを使用して実装できます。これは、Map<String,IImpl>の実装を格納します。ここで、keyはアルゴリズムの名前であり、valueはアルゴリズムの具体的な実装です。

共通のアプローチ:

は、インターフェースSolverのimlementations間で共有するすべてのパラメータを保持するクラスContextを考えてみましょう。必要なメソッドsolvename

public interface Solver { 
void solve(Context context); 
String name(); 
} 

public class Context extends HashMap<String,Object> { 
public <T> T get(String key, Class<T> resultClass){ 
    return resultClass.cast(get(key)); 
} 

public <T> T getOrDefault(String key, T def, Class<T> resultClass){ 
    return resultClass.cast(getOrDefault(key,def)); 
} 
} 

およびインターフェイスSolver次に、あなたが共有Contextオブジェクトを変更Solverインタフェースの実装を作成することができます。この例ではAddSolverMultiplySolverを作成しました。

AddSolver.java:

public class AddSolver implements Solver { 

@Override 
public void solve(Context context) { 
    context.put("result", context.getOrDefault("result",0.0, Double.class) + context.get("add", Double.class)); 
} 

@Override 
public String name() { 
    return "+"; 
} 
} 

MultiplySolver.java

public class MultiplySolver implements Solver { 
@Override 
public void solve(Context context) { 
    context.put("result", context.getOrDefault("result",0.0, Double.class) * context.get("multiply", Double.class)); 
} 
@Override 
public String name() { 
    return "*"; 
} 
} 

Map<String,Solver>の手動構成:インタフェースSolver

実装がに格納することができます

@Test 
public void testCustomFunctionMap(){ 
    HashMap<String,Solver> functionMap = new HashMap<>(); 
    functionMap.put("+", new AddSolver()); 
    functionMap.put("*", new MultiplySolver()); 

    Context context = new Context(); 
    context.put("add", 2.0); 
    functionMap.get("+").solve(context); 
    TestCase.assertEquals(2.0, context.get("result", Double.class)); 

    context.put("multiply", 3.0); 
    functionMap.get("*").solve(context); 
    TestCase.assertEquals(6.0, context.get("result", Double.class)); 
} 

自動的Map<String,Solver>をcostruct必要がある場合はより多くのアプローチが、ありMap<String,Solver>

の自動構築。それらの多くはthis questionに記載されています。私はorg.reflectionsライブラリを使用しました。

public class SolverScanner{ 
static HashMap<String, Solver> functionMap; 
static { 
     functionMap = new HashMap<>(); 
     Reflections reflections = new Reflections(SolverScanner.class.getPackage().getName()); 
     for(Class<? extends Solver> clazz : reflections.getSubTypesOf(Solver.class)){ 
      try { 
       Solver solver = clazz.newInstance(); 
       functionMap.put(solver.name(), solver); 
      } catch (Exception e) { 
       throw new IllegalStateException("Cannot construct functionMap",e); 
      } 
     } 
} 
public static HashMap<String, Solver> getFunctionMap(){ 
    return functionMap; 
} 
private SolverScanner(){}//disable instantiating 
} 

と使用方法:

@Test 
public void testSolverScannerFunctionMap(){ 
    HashMap<String,Solver> functionMap = SolverScanner.getFunctionMap(); 

    Context context = new Context(); 
    context.put("add", 2.0); 
    functionMap.get("+").solve(context); 
    TestCase.assertEquals(2.0, context.get("result", Double.class)); 

    context.put("multiply", 3.0); 
    functionMap.get("*").solve(context); 
    TestCase.assertEquals(6.0, context.get("result", Double.class)); 
} 
関連する問題