【问题标题】:Client/server - How to separate protocol from network logic?客户端/服务器 - 如何将协议与网络逻辑分开?
【发布时间】:2017-09-04 16:11:06
【问题描述】:

我想实现和单元测试(不一定是 TDD)一个客户端应用程序,它使用某种应用程序协议与 TCP 服务器通信。

我在here (1)here (2) 等地方看到,协议代码最好与网络代码分离,这样我每个人都可以单独进行单元测试。

但是我不明白我应该如何设计和实现这些部分。

第一个链接讨论了一个带有方法HelloMessage()HowdyMessage()MyProtocolHandler 类。这是否意味着协议处理程序应该有两种方法来生成消息和处理响应?我将如何使用它们?还有一件事,每个消息/响应对应该有不同的ProtocolHandler 类,还是只有一个类?

第二个链接谈到ReaderWriter。同样,我无法理解我应该如何使用它们。

这两个只是例子。主要问题是,我如何将逻辑与网络分离并对它们进行单元测试?我不得不说我还没有尝试过任何东西;我习惯了只写耦合代码,不知道从哪里开始。

【问题讨论】:

    标签: java unit-testing network-programming protocols network-protocols


    【解决方案1】:

    这些是处理任务的不同方式。网络堆栈被设计为不同的层,其中每一层为上层提供“定义明确”的功能,并通过 API 提供这些功能。

    因此,如果您想实现自己的在 TCP 或 SSL 上运行的应用层协议(这反过来可能会在 TCP 上运行),您将使用套接字接口。您设计该部分的方式与您设计任何应用程序的方式相同。通常,您希望将应用程序逻辑与协议分开,称之为 A,逻辑。您的协议 A 将负责使用套接字(写入和读取)向服务器发送消息,从服务器读取消息,处理超时(例如,当期望来自服务器的响应永远不会到达时),处理套接字错误、消息格式、消息解析等。协议 A 将对您的应用程序隐藏所有这些问题。

    您的应用程序将只处理您的协议提供的 API 函数:如 HelloMessage,它将调用该方法,在内部,HelloMessage 将处理套接字、消息格式等。

    现在您的协议 A 可以仅由一个类或一组类实现。如果它是一组类,我建议您将它们作为同一个包的一部分。

    详细说明如何实现它,我建议两个选项: 1)您有一个 Reader 和 Writer 类,它们是套接字的包装器。然后,您的协议类使用这些读取器和写入器,您可以在不使用不使用套接字的子读取器和写入器的网络的情况下对其进行测试。 2)这更复杂,你可以有一个通信类,它可以接收通过消息队列发送的消息,它也可以使用另一个消息队列发送接收到的消息。 Communication 类知道如何处理连接或套接字(取决于抽象级别)。它知道如何打开连接、处理超时等。这是一个更好的设计,但太复杂了。

    我希望这会有所帮助。

    【讨论】:

    • 这正是我实现它的方式,使用单个类。但是我对问题中链接文本的理解是,可以将使用套接字的代码(网络代码)与实现 API 的代码(协议代码)分开,因此我可以测试后者而不必实际执行网络。怎么做是我无法理解的。
    • @Piovezan,我添加了更多信息,但您必须努力解决此问题并提出设计。从简单的事情开始,然后你就会开始想出更好的方法。
    • 我将尝试选项 1。在选项 2 中,消息队列是指成熟的消息队列,例如 RabbitMQ 或常规 Java 队列?
    • @Piovezan,只是线程间通信的常规队列
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-03
    • 2015-12-14
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多