编写此Java代码的更好方法?

编写此Java代码的更好方法?,java,coding-style,Java,Coding Style,我有这部分服务器代码用于处理消息类型。每条消息都包含commandArr[0]中的类型和commandArr[]其余部分中的参数。然而,当前的代码在工作时似乎非常不公平。有没有更好的办法处理?据我所知,字符串值不能用在switch语句中,即使这样,switch语句也只是一个小小的改进。我会使用 基本上,您的每个命令message、quit、confirmconnect和一个默认命令都有一个类实现,并将实现命令接口 public void handleParsedCommand(String[]

我有这部分服务器代码用于处理消息类型。每条消息都包含commandArr[0]中的类型和commandArr[]其余部分中的参数。然而,当前的代码在工作时似乎非常不公平。有没有更好的办法处理?据我所知,字符串值不能用在switch语句中,即使这样,switch语句也只是一个小小的改进。

我会使用

基本上,您的每个命令message、quit、confirmconnect和一个默认命令都有一个类实现,并将实现命令接口

public void handleParsedCommand(String[] commandArr) {
    if(commandArr[0].equalsIgnoreCase("message")) {
        int target = Integer.parseInt(commandArr[1]);
        String message = commandArr[2];
        MachatServer.sendMessage(target, this.conId, message);
    } else if(commandArr[0].equalsIgnoreCase("quit")) {
        // Tell the server to disconnect us.
        MachatServer.disconnect(conId);
    } else if(commandArr[0].equalsIgnoreCase("confirmconnect")) {
       // Blah blah and so on for another 10 types of command
    } else {
        try {
            out.write("Unknown: " + commandArr[0] + "\n");
        } catch (IOException e) {
            System.out.println("Failed output warning of unknown command.");
        }
    }
}

我将使用

基本上,您的每个命令message、quit、confirmconnect和一个默认命令都有一个类实现,并将实现命令接口

public void handleParsedCommand(String[] commandArr) {
    if(commandArr[0].equalsIgnoreCase("message")) {
        int target = Integer.parseInt(commandArr[1]);
        String message = commandArr[2];
        MachatServer.sendMessage(target, this.conId, message);
    } else if(commandArr[0].equalsIgnoreCase("quit")) {
        // Tell the server to disconnect us.
        MachatServer.disconnect(conId);
    } else if(commandArr[0].equalsIgnoreCase("confirmconnect")) {
       // Blah blah and so on for another 10 types of command
    } else {
        try {
            out.write("Unknown: " + commandArr[0] + "\n");
        } catch (IOException e) {
            System.out.println("Failed output warning of unknown command.");
        }
    }
}
看看哪个是命令行参数解析器

下面是它的用法。

看看哪个是命令行参数解析器


以下是它的用法。

您可以使用

您可以使用

对于初学者,我将在命令和执行每种命令类型的类之间建立一个映射,比如一个实现已知接口的匿名类,然后从映射中检索正确的类,然后将其余参数传递给它


如果有意义的话,您可以在这里使用带有静态方法的枚举来检索正确的方法,这样您就可以在需要对10个命令中的5个命令执行相同操作时进行切换。

对于初学者,我将在命令和执行每种命令类型的类之间建立一个映射,比如一个实现已知接口的匿名类,然后从映射中检索正确的类,然后将其余参数传递给它


如果有意义的话,您可以在这里使用带有静态方法的枚举来检索正确的方法,这样您就可以在需要对10个命令中的5个命令执行相同操作时进行切换。

首先,每次读取数组的相同元素。这应该是第一件要考虑的事情。equalsIgnoreCase有点长,所以请先规范化案例,不要选择默认区域设置


可以使用enum来破解swting的切换。JDK7可能包含一个打开字符串IIRC。

首先,您每次都在读取数组的同一元素。这应该是第一件要考虑的事情。equalsIgnoreCase有点长,所以请先规范化案例,不要选择默认区域设置


可以使用enum来破解swting的切换。JDK7可能包括一个打开字符串IIRC。

我喜欢Bob的答案。另一种方法是使用Spring框架和IoC功能。基本上,我之前已经使用Spring从xml膨胀来创建一个映射,其中每个命令对象都存储有一个键。该键与commandArr[0]中的文本相同

所以您的xml看起来像

/*the Command interface*/
public interface ICommand {
    void execute(String[] commandArr);
}

public class Message implements ICommand {
    void execute(String[] commandArr) {
        int target = Integer.parseInt(commandArr[1]);
        String message = commandArr[2];
        MachatServer.sendMessage(target, this.conId, message);
    }
}

//same type of class for other commands

public class CommandManager {
    public ICommand getCommand(String commandName) {
        //store all the commands in a hashtable. 
        //Pull them out by name as requested.
    }

    //Esko's suggestion from comments
    public static void executeImmediately(String[] commandArr) {
        getCommand(commandArr[0]).execute(commandArr);
    }
}


public void handleParsedCommand(String[] commandArr) {

    ICommand command = CommandManager.getCommand(commandArr[0]);
    command.execute(commandArr);

//or Esko

    CommandManager.executeImmediately(commandArr);

}
这允许您不运行任何类型的初始化代码。您所要做的就是膨胀xml。Spring处理为您填充地图的操作。此外,您还可以使用类似的语法在类中定义任何必要的数据成员。此外,如果您需要添加功能,您所要做的就是更改xml,而不是修改和重新编译代码。我个人是一个火狗迷:


要了解更多信息,请查看国际奥委会的简要概述,然后查看我喜欢鲍勃的答案。另一种方法是使用Spring框架和IoC功能。基本上,我之前已经使用Spring从xml膨胀来创建一个映射,其中每个命令对象都存储有一个键。该键与commandArr[0]中的文本相同

所以您的xml看起来像

/*the Command interface*/
public interface ICommand {
    void execute(String[] commandArr);
}

public class Message implements ICommand {
    void execute(String[] commandArr) {
        int target = Integer.parseInt(commandArr[1]);
        String message = commandArr[2];
        MachatServer.sendMessage(target, this.conId, message);
    }
}

//same type of class for other commands

public class CommandManager {
    public ICommand getCommand(String commandName) {
        //store all the commands in a hashtable. 
        //Pull them out by name as requested.
    }

    //Esko's suggestion from comments
    public static void executeImmediately(String[] commandArr) {
        getCommand(commandArr[0]).execute(commandArr);
    }
}


public void handleParsedCommand(String[] commandArr) {

    ICommand command = CommandManager.getCommand(commandArr[0]);
    command.execute(commandArr);

//or Esko

    CommandManager.executeImmediately(commandArr);

}
这允许您不运行任何类型的初始化代码。您所要做的就是膨胀xml。Spring处理为您填充地图的操作。此外,您还可以使用类似的语法在类中定义任何必要的数据成员。此外,如果您需要添加功能,您所要做的就是更改xml,而不是修改和重新编译代码。我个人是一个火狗迷:


有关更多信息,请查看IoC的简要概述,然后查看以下两个使用枚举的变体,它们几乎以更易读的方式提供相同的行为:

类型安全交换机的1个枚举:

主要的好处是代码更具可读性,但可以避免为每种情况创建新的方法或类,如果处理代码只有一行或两行,则不允许创建所需的方法或类

2另一种基于枚举的变体,实际上是一种命令模式,但会产生大量膨胀代码:


以下是使用枚举的两个变体,它们以更易读的方式提供了几乎相同的行为:

类型安全交换机的1个枚举:

主要的好处是代码更具可读性,但可以避免创建新的方法 ds或类,如果处理代码只有一行或两行,则不允许您想要的内容

2另一种基于枚举的变体,实际上是一种命令模式,但会产生大量膨胀代码:

是的,在我看来像一个+模式

在命令中定义要执行的操作,原型是在查找表中放置每个命令的一个实例,并克隆它们以便每次执行

重构过程如下所示:

之前:

enum CommandType {
    MESSAGE {
        void execute(CommandProcessor cp, String[] params) {
            int target = Integer.parseInt(params[1]);
            String message = params[2];
            MachatServer.sendMessage(target, cp.conId, message);        
        }
    },
    QUIT {
        void execute(CommandProcessor cp, params param) {
            MachatServer.disconnect(cp.conId);  
        }
    },
    CONFIRMCONNECT {
        void execute(CommandProcessor cp, params param) {
              // Blah blah and so on for another 10 types of command
        }
    };

    abstract void execute(CommandProcessor cp, String[] param);
}
public void handleParsedCommand(String[] commandArr) {
    CommandType cmd = null;

    try {
        cmd = CommandType.valueOf(commandArr[0].toUpperCase());
    } catch (IllegalArgumentException e) {
        try {
            out.write("Unknown: " + commandArr[0] + "\n");
        } catch (IOException e) {
            System.out.println("Failed output warning of unknown command.");
        }
        return;
    }
    cmd.execute(this, commandArr);
}
之后:

public void handleParsedCommand(String[] commandArr) {
        if(commandArr[0].equalsIgnoreCase("message")) {
        int target = Integer.parseInt(commandArr[1]);
        String message = commandArr[2];
        MachatServer.sendMessage(target, this.conId, message);
    } else if(commandArr[0].equalsIgnoreCase("quit")) {
        // Tell the server to disconnect us.
        MachatServer.disconnect(conId);
    } else if(commandArr[0].equalsIgnoreCase("confirmconnect")) {
       // Blah blah and so on for another 10 types of command
    } else {
        try {
            out.write("Unknown: " + commandArr[0] + "\n");
        } catch (IOException e) {
            System.out.println("Failed output warning of unknown command.");
        }
    }
}
是的,在我看来像一个+模式

在命令中定义要执行的操作,原型是在查找表中放置每个命令的一个实例,并克隆它们以便每次执行

重构过程如下所示:

之前:

enum CommandType {
    MESSAGE {
        void execute(CommandProcessor cp, String[] params) {
            int target = Integer.parseInt(params[1]);
            String message = params[2];
            MachatServer.sendMessage(target, cp.conId, message);        
        }
    },
    QUIT {
        void execute(CommandProcessor cp, params param) {
            MachatServer.disconnect(cp.conId);  
        }
    },
    CONFIRMCONNECT {
        void execute(CommandProcessor cp, params param) {
              // Blah blah and so on for another 10 types of command
        }
    };

    abstract void execute(CommandProcessor cp, String[] param);
}
public void handleParsedCommand(String[] commandArr) {
    CommandType cmd = null;

    try {
        cmd = CommandType.valueOf(commandArr[0].toUpperCase());
    } catch (IllegalArgumentException e) {
        try {
            out.write("Unknown: " + commandArr[0] + "\n");
        } catch (IOException e) {
            System.out.println("Failed output warning of unknown command.");
        }
        return;
    }
    cmd.execute(this, commandArr);
}
之后:

public void handleParsedCommand(String[] commandArr) {
        if(commandArr[0].equalsIgnoreCase("message")) {
        int target = Integer.parseInt(commandArr[1]);
        String message = commandArr[2];
        MachatServer.sendMessage(target, this.conId, message);
    } else if(commandArr[0].equalsIgnoreCase("quit")) {
        // Tell the server to disconnect us.
        MachatServer.disconnect(conId);
    } else if(commandArr[0].equalsIgnoreCase("confirmconnect")) {
       // Blah blah and so on for another 10 types of command
    } else {
        try {
            out.write("Unknown: " + commandArr[0] + "\n");
        } catch (IOException e) {
            System.out.println("Failed output warning of unknown command.");
        }
    }
}

什么版本的Java?SWITCH终于有了最新的字符串支持,还是已经发布了?版本..可能与此相关?什么版本的Java?SWITCH终于有了最新的字符串支持,还是已经发布了?版本..可能与此相关?它们不是命令行参数。他们来自网络。来源并不重要,真的。CLI将字符串[]作为输入。它们不是命令行参数。他们来自网络。来源并不重要,真的。CLI将字符串[]作为输入。我想知道您在这里描述的是策略模式,而不是命令模式吗?策略需要能够相互替换;它们是做同样事情的替代方法。我不认为这完全符合策略模式的应用。策略描述可插入的算法。例如,排序,您可以使用QuickSortStrategy或BubbleSortStrategy。两者的最终结果都是相同的,一个排序列表。但它是如何完成的是不同的。命令封装单个操作。如果您愿意,您可以实际执行CommandManager.executeimmediatelycommandar;它仅包装CommandManager.getCommandcommandArr[0].executecommandArr;内在的。这样,您的代码将变得非常非常干净。+1表示命令。您可以在getCommand方法中输入null,因此您也需要一个未知的命令。此外,如果需要保持实例状态,则需要创建新实例。请看我对这两种情况的回答。我想知道您在这里描述的是策略模式,而不是命令模式吗?策略需要能够相互替代;它们是做同样事情的替代方法。我不认为这完全符合策略模式的应用。策略描述可插入的算法。例如,排序,您可以使用QuickSortStrategy或BubbleSortStrategy。两者的最终结果都是相同的,一个排序列表。但它是如何完成的是不同的。命令封装单个操作。如果您愿意,您可以实际执行CommandManager.executeimmediatelycommandar;它仅包装CommandManager.getCommandcommandArr[0].executecommandArr;内在的。这样,您的代码将变得非常非常干净。+1表示命令。您可以在getCommand方法中输入null,因此您也需要一个未知的命令。此外,如果需要保持实例状态,则需要创建新实例。这两种情况见我的答案。
class MessageCommand extends Command {
     public void execute(){
        int target = Integer.parseInt(commandArr[1]);
        String message = commandArr[2];
        MachatServer.sendMessage(target, this.conId, message);
     }
}

class MessageCommand extends Command {
     public void execute(){
        int target = Integer.parseInt(getArgs()[1]);
        String message = getArgs()[2];
        MachatServer.sendMessage(target, this.conId, message);
     }
}

class QuitCommand extends Command {
     public void execute() {
      MachatServer.disconnect(conId);
     }
 }

 class ConfirmConnectCommand extends Command {
     public void execute() {
     /// blah blah blah 
     }
 }
 class UnknowCommand extends Command  {
     public void execute() {
         try {
            out.write("Unknown: " + commandArr[0] + "\n");
         } catch (IOException e) {
            System.out.println("Failed output warning of unknown command.");
         }
     }
 }

 // ... other 10 implementations here...