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 具有内部类的请求-响应流模式_Java_Design Patterns_Serialization - Fatal编程技术网

Java 具有内部类的请求-响应流模式

Java 具有内部类的请求-响应流模式,java,design-patterns,serialization,Java,Design Patterns,Serialization,我有一个由两个进程组成的应用程序,一个带有(基于SWT的)GUI的客户端进程和一个服务器进程。客户端进程是非常轻量级的,这意味着许多GUI操作将不得不查询服务器进程或请求它,例如响应用户单击按钮或选择菜单项。这意味着将有许多事件处理程序如下所示: // Method invoked e.g. in response to the user choosing a menu item void execute(Event event) { // This code is executed o

我有一个由两个进程组成的应用程序,一个带有(基于SWT的)GUI的客户端进程和一个服务器进程。客户端进程是非常轻量级的,这意味着许多GUI操作将不得不查询服务器进程或请求它,例如响应用户单击按钮或选择菜单项。这意味着将有许多事件处理程序如下所示:

// Method invoked e.g. in response to the user choosing a menu item
void execute(Event event) {
    // This code is executed on the client, and now we need some info off the server:
    server.execute(new RemoteRequest() {
        public void run() {
            // This code is executed on the server, and we need to update the client 
            // GUI with current progress
            final Result result = doSomeProcessing();
            client.execute(new RemoteRequest() {
                public void run() {
                    // This code is again executed on the client
                    updateUi(result);
                }
            }
        }
    });
}
void execute(Event event) {
    static_execute(server, client, event);
}

// An anonymous class is static if it is defined in a static method. Let's use that.
static void static_execute(final TheServer server, final TheClient client, final Event event) {
    server.execute(new RemoteRequest() {
        public void run() {
            final Result result = doSomeProcessing();
            // See note below!
            client.execute(new RemoteRequest() {
                public void run() {
                    updateUi(result);
                }
            });
        }
    });
}
但是,由于
server.execute
意味着序列化(在远程计算机上执行),如果不使整个类可序列化(因为
RemoteRequest
内部类不是静态的),则不可能使用此模式(需要明确的是:
请求
实现不需要访问父实例,因为应用程序可能是静态的)

当然,一种解决方案是为请求和响应创建单独的(可能是静态的内部)类,但这会损害可读性,并使执行流更难理解

我试图找到任何解决这个问题的标准模式,但我没有找到任何解决我对可读性的担忧的方法

需要明确的是,这些操作会有很多,而且操作通常很短。请注意,
Future
对象在这里并不完全有用,因为在许多情况下,对服务器的一个请求将需要在客户端上执行多个操作(通常是不同的),并且也不总是返回结果

理想情况下,我希望能够编写如下代码:(现在是明显的伪代码,请忽略细节中明显的错误)

现在我想澄清的是,底层架构已经就位并且运行良好,这个解决方案存在的原因当然不是上面的示例。我唯一要寻找的是一种编写类似上面的代码的方法,而不必为每个进程转换定义静态类。我希望我不只是通过giv使事情复杂化在这个例子中…

我的首选是使用和通用异步回调。例如,在GWT中,这种方法用于与服务器通信。命令是可序列化的,异步回调是一个接口

大致如下:

    // from the client
    server.execute(new GetResultCommand(args), new AsyncCallback<Result>() 
            {
                public void onSuccess(Result result) {
                    updateUi(); // happens on the client
                }
            });
//来自客户端
execute(新的GetResultCommand(args),新的AsyncCallback()
{
成功时公开作废(结果){
updateUi();//在客户端上发生
}
});

然后,服务器需要接收命令,对其进行处理并发出相应的响应,并给出相应的结果。

前几天我遇到了类似的问题。 有一种解决方案使用匿名类(因此不需要定义静态内部类),但使这些匿名类是静态的(因此不引用外部对象)

只需在静态方法中定义匿名类,如下所示:

// Method invoked e.g. in response to the user choosing a menu item
void execute(Event event) {
    // This code is executed on the client, and now we need some info off the server:
    server.execute(new RemoteRequest() {
        public void run() {
            // This code is executed on the server, and we need to update the client 
            // GUI with current progress
            final Result result = doSomeProcessing();
            client.execute(new RemoteRequest() {
                public void run() {
                    // This code is again executed on the client
                    updateUi(result);
                }
            }
        }
    });
}
void execute(Event event) {
    static_execute(server, client, event);
}

// An anonymous class is static if it is defined in a static method. Let's use that.
static void static_execute(final TheServer server, final TheClient client, final Event event) {
    server.execute(new RemoteRequest() {
        public void run() {
            final Result result = doSomeProcessing();
            // See note below!
            client.execute(new RemoteRequest() {
                public void run() {
                    updateUi(result);
                }
            });
        }
    });
}
与使用命名静态内部类相比,这种方法的主要优点可能是避免了为这些类定义字段和构造函数

--想一想,同样的技巧可能需要再次应用,用于服务器->客户端方向。我将把这作为一个练习留给读者:-)

首先: 如果没有模式,如果我建议的话,你可以创建一个单独的类来处理所有模式。只需将每个事件生成对象的实例传递给一个类,并将事件请求委托给其他类。委托将导致非常清晰的方法,只需使用instanceof,然后进一步委托。每个事件都可以简洁到分开的地方。
除了上述方法之外,是的,命令模式无疑是记录请求的一个很好的选择,但您将获得每个请求的事件状态,因此您可以尝试使用状态模式,因为它允许对象在状态更改时改变其行为。

我实际上通过创建一个带有自定义序列化程序的基类来解决这个问题,该序列化程序采用让我们来处理这个问题。我仍然希望最终能用语言来解决这个问题。

这与jms有什么关系?这段代码是在客户机、服务器还是其他机器上执行的?是的,是的。有些情况下,代码是在客户机和服务器上执行的。有些情况下,客户机在服务器上执行某些东西,而服务器又执行某些东西关于客户端的事情。我想我们需要更多的细节。请求/响应是您自己的类还是它们是某个框架的一部分?execute到底做什么?我更新了这个问题,并试图更清楚地了解我要实现的目标。我想如果您提供一个示例用例会有所帮助。在这种情况下,“AsyncCallback”不是一个非参数吗-静态内部类?如何在不需要序列化外部类的情况下将其序列化到服务器?AsyncCallback不需要序列化和发送。
服务器
对象只保留对它的引用,然后在结果对象从实际服务器到达时调用它。只有命令和结果需要序列化。你可以这样做虽然我的问题是希望
GetResultCommand
作为一个匿名类在线,但是
AsyncCallback
对我来说并不重要(尽管这会很好)。谢谢你提到这一点。我考虑过这样的解决方案,但事实证明,在我的情况下,代码变得更加复杂,以这种方式编写。