2009-03-31 16 views
1

私は、単純な分散Java RMIアプリケーションを書いていると私はそうのような、それぞれがこれらのインターフェース上の様々な他のメソッドを呼び出すために、クライアント・インタフェースのマップを反復処理する必要がある方法、の束がありますこのJavaコードを記述するのに最も簡潔で/最良の方法は何ですか?

public void methodX (arg1, arg2) { 
    Iterator<String> itr = clients.keySet().iterator; 
    while (itr.hasNext()) { 
    String name = itr.next(); 
    if (!"mod".equals(name)) { 
     try { 
     clients.get(name).methodXX(arg1, arg2); 
     } catch(RemoteException ex) { 
     // do something 
     } 
    } 
    } 
} 

public void methodY (arg1, arg2, arg3) { 
    Iterator<String> itr = clients.keySet().iterator; 
    while (itr.hasNext()) { 
    String name = itr.next(); 
    if (!"mod".equals(name)) { 
     try { 
     clients.get(name).methodYY(arg1, arg2, arg3); 
     } catch(RemoteException ex) { 
     // do something 
     } 
    } 
    } 
} 
を代わりに、彼らはそれぞれそのように、MESSAGE_TYPEと呼ばれる新しい引数を渡すことで、単一のメソッドDOALLを呼び出すように

は今、私はこれらを修正:

public void methodX (arg1, arg2) { 
    doAll(MESSAGE_TYPE.METHODX, arg1, arg2, null); 
} 

public void methodY (arg1, arg2, arg3) { 
    doAll(MESSAGE_TYPE_METHODY, arg1, arg2, arg3); 
} 

そしてDOALL方法:

public void doAll(msg_type, arg1, arg2, arg3) { 
Iterator<String> itr = clients.keySet().iterator; 
    while (itr.hasNext()) { 
    String name = itr.next(); 
    if (!"mod".equals(name)) { 
     try { 
     switch(msg_type) { 
      case METHODX: 
      clients.get(name).methodXX(arg1, arg2); 
      break; 
      case METHODY: 
      clients.get(name).methodYY(arg1, arg2, arg3); 
      break; 
     } 
     } catch(RemoteException ex) { 
     // do something 
     } 
    } 
    } 
} 

これほどたくさんのメソッドがあります。したがって、doAllメソッドはたくさんの引数を取り、それを呼び出すメソッドXXはそれにヌルを渡します。

これを書き換えてより簡潔にすることはできますか?もしそうなら、あなたは例を挙げることができますか?

+1

"...シンプルな分散Java rmiアプリケーション..."多くの擬態語? –

答えて

9

一つには、私は、拡張forループを使用したい、とのコメントで示唆されているように、代わりにキーのエントリを反復:

public void doAll(arg1, arg2, arg3) { 
    for (Map.Entry<String,Client> entry : clients.entrySet()) { 
    if (!"mod".equals(entry.getKey())) { 
     try { 
     switch(MESSAGE_TYPE) { 
      case METHODX: 
      entry.getValue().methodXX(arg1, arg2); 
      break; 
      case METHODY: 
      entry.getValue().methodYY(arg1, arg2, arg3); 
      break; 
     } 
     } catch(RemoteException ex) { 
     // do something 
     } 
    } 
    } 
} 

は、私は、その後に合格することをリファクタリングと思います

public interface RemoteAction { 
    public void execute(Client client) throws RemoteException; 
} 

public void doAll(RemoteAction action) { 
    for (Map.Entry<String,Client> entry : clients.entrySet()) { 
    if (!"mod".equals(entry.getKey())) { 
     try { 
     action.execute(entry.getValue()); 
     } catch(RemoteException ex) { 
     // do something 
     } 
    } 
    } 
} 

public void methodX (final arg1, final arg2) { 
    doAll(new Action() { 
    @Override public void execute(Client client) throws RemoteException { 
     client.methodX(arg1, arg2); 
    } 
    }); 
} 

public void methodY (final arg1, final arg2, final arg3) { 
    doAll(new Action() { 
    @Override public void execute(Client client) throws RemoteException { 
     client.methodY(arg1, arg2, arg3); 
    } 
    }); 
} 

は、それはラムダ式をサポートしている言語になりほど素敵ではないのですが、それはswitch文よりも立派だ:各クライアントで呼び出し、呼び出しサイトから匿名内部クラスを使用するには、「アクション」 。

+0

keySetで "get"を呼び出すのではなく、entrySetを繰り返し処理すると、勝者がいると思います。 – erickson

+0

私はそれを考えていました。さて、答えを変更する:) –

0

使用ジェネリック

Iterator<String> itr = clients.keySet().iterator; 
while (itr.hasNext()) { 
    String name = itr.next(); 

for(String name: clients.keySet()){ 

なりまた、スイッチ/ケースとメソッドを交換することで、未使用の値のためのダミーパラメータに渡す必要がある場合は特に、あまりよくないです。別々の方法を保つ。文脈に応じて、

-2

(時々、セキュリティマネージャやプロキシが邪魔になる)、イントロスペクションと可変引数はあなたの友達です:

次のようなものかもしれない:

void callStuff(String methodName, Object ... args) 
{ 
    for(Client client: clients) 
    { 
    //...filter client by name, method, etc. 
    //...figure out parameter types - you can guess from args or pass another parameter 
    Method method = client.getClass().getMethod(methodNamename, parameterTypes); 
    method.invoke(client,args); 
    } 
} 

(免責事項:上記のコードをテストされておらず、イベントがコンパイルされていない - と私はそれがRMIで動作するかどうか手がかりがない)

-1

あなたのメソッドをより簡潔にすることについては知らないが、doAllメソッドのパラメータについての提案が...

public void doAll(int methodType, Object... arg) 
{ 
    //snip 
    switch(msg_type) 
    { 
     case METHODX: 
      clients.get(name).methodXX(arg[0], arg[1]); 
      break; 
     case METHODY: 
      clients.get(name).methodYY(arg[0], arg[1], arg[2]); 
      break; 
    } 
    //snip 
} 

これにより、doAllメソッドに可変数のargsを渡すことができ、nullの必要性が緩和されます。

関連する問題