2016-06-26 5 views
4

私は到着した文字列パラメータに応じていくつかのメソッドを実行しようとしています。 「ターミナル」のリストからいくつかの機能を有効にしたり無効にしたりすることが考えられます。 クラスはコマンドパターン用に設計されており、しばらくのうちに "doProcess"が呼び出されますHashMapをビルダーとして使用するには?

私の実際の解決策はひどいので、HashMapを作ることを考えます。たとえば、次のように map.put(「メール」、activateMailsOfTerminals)

しかし、私は動的にコンストラクタに来る文字列のリストに応じて(...、activateMailsOfTerminals無効)関数を呼び出す方法を知らない

ありがとうございます!

悪いソリューション:

public class ActionsActivator { 

    Set <Terminal> terminals = new HashSet < >(); 
    Set <String> activate = new HashSet < >(); 
    Set <String> deactivate = new HashSet < >(); 

    public ActionsActivator(Set <Terminal> filteredTerminals, Set <String> active, Set <String> deactive) { 
     this.terminals = Map().getInstance().getTerminals; 
     this.activate.addAll(activate); 
     this.deactivate.addAll(deactivate); 
    } 

    public void doProcess() { 
     if (hasElement(activate, "Mail")) terminals.forEach(terminal - > terminal.activateMails()); 
     if (hasElement(activate, "Register")) terminals.forEach(terminal - > terminal.activateRegisters()); 

     if (hasElement(deactivate, "Mail")) terminals.forEach(terminal - > terminal.deactivateMails()); 
     if (hasElement(deactivate, "Register")) terminals.forEach(terminal - > terminal.deactivateRegisters()); 
    } 

    private Boolean hasElement(Set <String> list, String element) { 
     return list.stream().anyMatch(elem - > elem.equals(element)); 
    } 
} 
+0

したがって、現在のソリューションは、 'activateMails()'と 'activateRegiters()'メソッドの呼び出しをハードコードします。これらの関数をコンストラクタに渡したいと思っていることを正しく理解していますか? – augray

+0

必ずしも、私は文字列(hasElementとifs)をチェックしたくありません。最も良い方法は、文字列パラメータリスト – user3166722

答えて

2

私は私の理解で正しいだ場合は、「ターミナル」のセットを持っている、とあなたは「活性化」は、端末上のいくつかのメソッド呼び出し/呼び出しを行い、オブジェクトをしたいです提供されます。それを達成し、デモする必要があり、次の

import java.util.Arrays; 
import java.util.HashMap; 
import java.util.HashSet; 
import java.util.Map; 
import java.util.Set; 
import java.util.function.Consumer; 

public class CommandsDemo { 

    public static class ActionsActivator{ 
     private Set<Terminal> terminals; 
     private Set<Consumer<Terminal>> actionsToPerformOnTerminals = new HashSet<>(); 

     public ActionsActivator(Set<Terminal> terminals, Consumer<Terminal>... actionsForTerminals){ 
      this.terminals = terminals; 
      actionsToPerformOnTerminals.addAll(Arrays.asList(actionsForTerminals)); 
     } 

     public void doProcess(){ 
      for(Consumer<Terminal> action : actionsToPerformOnTerminals){ 
       terminals.stream().forEach(action); 
      } 
     } 
    } 

    public static class Terminal{ 
     private final String name; 

     public Terminal(String name){ 
      this.name = name; 
     } 

     public void activateMails(){ 
      System.out.println("Activated mail for: "+name); 
     } 
     public void activateRegisters(){ 
      System.out.println("Activated registers for: "+name); 
     } 
    } 

    public static void main(String[] args){ 
     Terminal terminalA = new Terminal("terminalA"); 
     Terminal terminalB = new Terminal("terminalB"); 
     Terminal terminalC = new Terminal("terminalC"); 

     Set<Terminal> terminals = new HashSet<>(); 
     terminals.addAll(Arrays.asList(terminalA, terminalB, terminalC)); 

     ActionsActivator mailActivator = new ActionsActivator(terminals, (terminal)->terminal.activateMails()); 

     ActionsActivator registerActivator = new ActionsActivator(terminals, (terminal)->terminal.activateRegisters()); 

     ActionsActivator mailAndRegisterActivator = new ActionsActivator(terminals, 
       (terminal)->terminal.activateMails(), 
       (terminal)->terminal.activateRegisters()); 

     System.out.println("Running mail activator"); 
     mailActivator.doProcess(); 

     System.out.println("Running register activator"); 
     registerActivator.doProcess(); 

     System.out.println("Running mail & register activator"); 
     mailAndRegisterActivator.doProcess(); 
    } 

} 

出力:それは可能私たちがコマンドを設定できるようになり

Running mail activator 
Activated mail for: terminalC 
Activated mail for: terminalA 
Activated mail for: terminalB 
Running register activator 
Activated registers for: terminalC 
Activated registers for: terminalA 
Activated registers for: terminalB 
Running mail & register activator 
Activated registers for: terminalC 
Activated registers for: terminalA 
Activated registers for: terminalB 
Activated mail for: terminalC 
Activated mail for: terminalA 
Activated mail for: terminalB 

重要なのは、/各端末に呼び出されるコマンドの一般的なConsumerクラスですこれは、一般的に宣言された型のオブジェクトのインスタンスを引数として呼び出すことができるかどうかを表します。例:

Consumer<String> myConsumer = (str)->{System.out.println("Hello, "+str)}; 

myConsumer.accept("World"); 
myConsumer.accept("Venus"); 
myConsumer.accept("Mars"); 

プリント:Terminalを消費し、上の所望のメソッドを呼び出すConsumer<Terminal>一連のオブジェクトに渡すことによってそう

Hello, World 
Hello, Venus 
Hello, Mars 

は、我々は、設定を呼び出すActionsActivatorを行うことができ、Terminal Sを前記しましたメソッド/メソッドを提供します。使用する次に

private static Map<String, Consumer<Terminal>> activations = new HashMap<String, Consumer<Terminal>>() {{ 
    put("Mail", Terminal::activateMails); 
    put("Register", Terminal::activateRegisters); 
    // etc 
}}; 
// similar for deactivate 

+0

だけでメソッドを呼び出すことです!大変ありがとうございます – user3166722

+0

ありがとうございました。この作業を行う際に「消費者」が果たした重要な役割の説明については、編集を参照してください。 – augray

0

はマップを使用

public void doProcess() { 
    activate.stream() 
     .map(activations::get) 
     .filter(a -> a != null) 
     .forEach(a -> terminals.forEach(a)); 
    // similar for deactivate 
} 

このアプローチは宣言アクションの任意の多数を扱います。

関連する問題