Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我应该在TCP服务器代码中对多种类型的请求使用命令模式吗?_Java_Design Patterns_Serversocket_Command Pattern - Fatal编程技术网

Java 我应该在TCP服务器代码中对多种类型的请求使用命令模式吗?

Java 我应该在TCP服务器代码中对多种类型的请求使用命令模式吗?,java,design-patterns,serversocket,command-pattern,Java,Design Patterns,Serversocket,Command Pattern,要求: 在java中通过socket API实现TCP服务器,该服务器可以同时处理多个客户端。 服务器无法添加/删除。。。XML文本文件中的项目(作为数据存储) 客户端可以向服务器发送命令,如“addItem”/“removietem”。。 如果客户端发送了一个“addItem”,则应向XML文档添加一个新节点 是否应该使用命令设计模式? 如果是的话,哪个应该是命令、接收者、调用者、客户端 我的实现如下(还有评论中的一些问题): 接口命令{ 公共无效执行(); } AddItemCommand实

要求: 在java中通过socket API实现TCP服务器,该服务器可以同时处理多个客户端。 服务器无法添加/删除。。。XML文本文件中的项目(作为数据存储) 客户端可以向服务器发送命令,如“addItem”/“removietem”。。 如果客户端发送了一个“addItem”,则应向XML文档添加一个新节点

是否应该使用命令设计模式? 如果是的话,哪个应该是命令、接收者、调用者、客户端

我的实现如下(还有评论中的一些问题):

接口命令{
公共无效执行();
}
AddItemCommand实现该命令{
//接受者
XMLFileHelper;
//数据需要添加到XML文件中
//这些数据是否应该在这里??
ItemNode addedNode;
public AddItemCommand(XMLFileHelper newHelper){
xmlHelper=newHelper;
}
public void execute(){
addItemNode(addedNode);
}
}
/*此类将处理所有xml文档操作:添加、删除。。。
我想,应该是听筒
DataHelper在父接口中,子类可以是XMLFileHelper、DBHelper、MessageQueueHelper。。。
*/
公共类XMLFileHelper实现DataHelper{
}
RemoveItemCommand实现命令(){
//...............
}
/*这是调用程序,我不确定它应该是什么,所以我没有一个好名字*/
公共类调用程序{
Map Map=newhashmap();
public void addCommand(字符串cmdName,命令c){
map.put(cmdName,c);
}
public void processRequest(字符串reqName){
get(reqName.execute();
}
}
TcpServerThread实现可运行的{
公开募捐{
DataHelper xmlPaser=新的XMLFileHelper();
Command cmd1=新的AddItemCommand();
Command cmd2=new removietemcommand();
Invoker Invoker=newinvoler();
addCmd(“add”,cmd1);
addCmd(“remove”,cmd2);
字符串cmdName=getCommandName(socket.getInputStream());
processRequest(cmdName);
}
}

我不确定您想问的主要问题是什么,但我的直觉告诉我,您正在寻找某种形式的确认,以确定您的方法是否正确

所以要回答这个问题,你应该思考一下这个应用程序的要求是什么。 如果您希望TcpServer成为应用程序的中心点,而TcpServer是该事务中唯一一个向客户机提供某些服务的端,并且您希望使用集中式存储,那么这种方法是非常好的。您的设计允许您轻松测试所有代码单元(唯一的例外是TcpServerThread,它在运行方法中做了太多的工作,并且有隐藏的依赖项。我的意思是它初始化命令,将它们添加到调用程序并执行。我将把这些命令拆分到init并运行逻辑,调用程序将从外部注入。调用程序的安装工作将在其他地方执行)

我认为命令模式非常适合这里。您也可以考虑从以下命令更改命令接口:

interface Command{
  void execute();
}
差不多

interface Command{
  ResponseType execute( Parameters params );
}
ResonsType将使您能够将反馈传递给客户端。而使用注入的参数执行类型将使您能够使用参数管理请求

现在让我们关注Invoker类。您问过这个名称是否好。当我试图找出好的描述性名称时,我总是遵循的过程是什么?我问了一个问题:“这个类的主要目的是什么,它在做什么?” 在您的情况下,调用程序正在存储命令(CommandRegister?)在HashMap中,还引入了另一个层,这样TcpServer就不会直接调用命令。所以这感觉像是该类的另一个责任。您真的需要调用程序来处理请求吗?您是否计划在执行命令之前执行一些额外的工作?如果不需要,那么可能最好用其他方法替换调用程序这样做:

class CommandRegister{
    Map<String, Command> map = new HashMap<String, Command>();

    public void addCommand(String cmdName, Command c){
        map.put(cmdName, c);
    }


    public Command getCommand(String reqName){
        return map.contains(reqName) ? map.get(reqName) : null;
   }
}
但是,如果你的应用程序很简单,并且你不打算在命令执行层做额外的工作,那么你可以一直使用你的调用程序


如果有什么不清楚的地方,请告诉我;)

@Luke:是的,我在寻求确认。我开始学习java中的命令模式,所以我不确定这里是否应该使用命令模式。我试图在谷歌上搜索更多真实世界的命令模式示例,但只是找到了一些非常简单的演示。 因此,尝试实现一个简单的TCP服务器。可能稍后我将尝试观看tomcat的源代码,以检查它们是如何设计和实现服务器的,如果它们使用命令模式的话。 就像你说的,命令模式适合这里。谢谢你。
但是我担心command和invoker对象的构造应该放在线程的run方法中,因为当客户端尝试连接时,我计划使用一个线程(带有套接字obj)来处理来自同一客户端的所有请求。因此,只有线程知道客户端发送了哪个命令。为execute()添加返回类型可能是个不错的选择。

是的,我正在寻找一些确认信息。我开始学习java中的命令模式,所以我不确定这里是否应该使用命令模式。我试图在谷歌上搜索更多真实世界的命令模式示例,但只是找到了一些非常简单的演示。因此,尝试实现一个简单的TCP服务器。可能稍后我将尝试观看tomcat的源代码,以检查它们是如何设计和实现服务器的,如果它们使用命令模式的话。fdsmy注释太长,所以我将其放在下一个答案中。我没有忽略这样一个事实,即调用程序应该可用于您的TCpServer线程,但我声明线程应该已经准备好调用程序。初始化所有可用命令不应该是TcpServer的任务。这应该在外部完成,线程应该通过构造函数参数获得依赖关系。您应该对套接字执行相同的操作,以便可以模拟和测试它们。拥有我的另一个好处
class CommandRegister{
    Map<String, Command> map = new HashMap<String, Command>();

    public void addCommand(String cmdName, Command c){
        map.put(cmdName, c);
    }


    public Command getCommand(String reqName){
        return map.contains(reqName) ? map.get(reqName) : null;
   }
}
class CommandInvoker{
  public CommandInvoker(CommandRegister cR){
    this.cR = cR;
  }

  public void execute(String cmdName){
     Command cmd = cR.get(cmdName);
     cmd.execute(); //if you decided like me to return null if there is no Command with specific name in register you should also check if cmd is not null before calling execute.
  }
}