代码之家  ›  专栏  ›  技术社区  ›  JRL

编写这段java代码最简洁/最好的方法是什么?

  •  1
  • JRL  · 技术社区  · 17 年前

    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
          }
        }
      }
    }
    

    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
          }
        }
      }
    }
    

    我可以重写一下,使其更简洁吗?如果是这样,你能举个例子吗?

    4 回复  |  直到 17 年前
        1
  •  9
  •   Jon Skeet    17 年前

    首先,我会使用增强的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);
        }
      });
    }
    

    它不像支持lambda表达式的语言那样好,但它比switch语句更好。

        2
  •  0
  •   Thilo    17 年前

    使用泛型

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

    成为

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

    此外,用开关/case替换方法也不太好,特别是如果你需要为未使用的值传递虚拟参数。保持单独的方法。

        3
  •  -1
  •   masher    17 年前

    我不知道如何使你的方法更简洁,但我对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的需求。

        4
  •  -2
  •   ptyx    17 年前

    你可以有这样的东西:

    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)