【问题标题】:Java Client/Server applicationJava 客户端/服务器应用程序
【发布时间】:2012-08-25 08:44:35
【问题描述】:

我有一个多线程服务器,正在等待套接字连接。

第一次交换的消息总是同类型的,客户端发送一个带有认证细节的对象(userid/pwd),服务器检查它并回复服务器是否认证通过。

在第一次消息交换之后,客户端将发送一些请求,对应于服务器能够执行的各种任务。 我如何为这些异类请求建模?特别是我的问题是关于使用 InputObjecStream/OutputObjectStream 在客户端和服务器之间发送的对象类型

我有两个想法:

  1. 使用“通用消息”对象,具有 2 个属性:一个任务标识符和一个没有泛型的 HashMap,能够携带执行任务所需的各种类型的参数。

  2. 每个类型的任务一个对象,这个解决方案“更干净”,但是不知道如何让服务器理解接收到的消息的类型,我想到了一系列的对象转换从客户端接收到的消息到每个可能的“特定任务消息”,忽略许多 CastException。听起来很糟糕,有什么办法可以避免这种情况?

【问题讨论】:

  • 如果选择路线2,请使用instanceof

标签: java sockets client-server


【解决方案1】:

为什么不把这两个想法结合起来

从服务器可以投射的通用级别接口开始,以确定它应该做什么或现在做出反应。

随着对象被传递给负责处理请求的处理程序,可以进一步转换对象(基于更深层次的接口实现)

恕我直言

【讨论】:

  • 好主意,我真的很喜欢它:它听起来比访问者模式更简单,只需要 1 个额外的接口而不是 2 个(元素和访问者) 我将阅读更多关于访问者设计的内容模式,但我想我会使用这个解决方案
【解决方案2】:

第一种方法非常通用,但很难维护。一段时间后,您会注意到您不再记得该通用地图中应该包含哪些类型的对象。您必须保持字典同步。

第二种方法要好得多。本质上,您会收到一个带有各种子类的抽象 Request 对象。基类可以保存一些一般信息。通常你会使用多态性并在每个子类中实现动作,覆盖Request 类的抽象方法。但你不能,因为请求对象必须持有服务器端逻辑。

你可以在这里做的最好的是design pattern。有了它,以稍微模糊代码的代价,您将获得非常通用和安全的设计。 instanceof 会在一段时间后变得丑陋。

【讨论】:

  • 我刚看了一些关于访问者模式的东西,我以前从未使用过,在您的设计中访问者应该是处理消息并执行任务的方法,而访问元素是消息?跨度>
  • @mark: 是的,抽象的Request 类有accept(visitor) 方法,具体的访问者基于真实的Request 类型实现不同的处理程序方法。不需要子类化和instanceof
  • 由于我只需要 1 个具有大量重载 visit() 方法的具体访问者,我应该避免访问者界面并直接使用具体访问者吗?对我来说似乎没用
  • @mark:是的,拥有Visitor 接口和具体实现是没有意义的。您可以在需要时拆分它们。
【解决方案3】:

您可以使用XML 消息进行通信。您可以在第一个字节中预先指示消息应该映射到哪个 XML 对象,并且在接收到消息时,只需检查这些字节找到指示符,然后使用其余字节序列将字节编组为 XML 对象(使用 @ 987654323@ 或 SimpleXMLDOM 或任何其他 xml 解析器)XML 非常冗长,您可以在此处使用它来封装您的消息。

【讨论】: