我正在开发一种与设备通信的软件。
软件将为设备发送命令。设备必须使用以下协议回答:
<STX><STX><COMMAND>[<DATA_1><DATA_2>...<DATA_N>]<CHKSUM><ETX>
其中:
<STX> is the Start of TeXt (0x55);
<COMMAND> can be 0x01 for read, 0x02 for write, etc;
<DATA> is any value;
<CHKSUM> is the checksum;
<ETX> is the End of TeXt (0x04).
所以,我必须验证收到的数据。
然后,收到的数据:
如果答案有效,那么我可以处理数据。但在此之前我必须从收到的回复中提取这些数据。
好的,这是一项相对容易的任务。之前我会以程序的方式进行,只使用一个函数并放入许多if。
现在我正在研究更好的编程实践,事情似乎越来越难。
要验证设备答案,最好创建一个类“ValidateReceivedData”,并在此类的构造函数中传递接收的数据?然后创建一个名为“IsReceivedDataValid”的公共方法,检查上面给出的所有步骤?
或者更好的是创建一个具有多个函数的库来验证收到的数据?
我也想使用单元测试。
正如我之前所说,我正在研究更多以制作更好的代码。但我意识到我现在花费的时间比以前更多。并且有太多问题出现了,但在我看来,它们似乎很容易解决,但我没有得到。
答案 0 :(得分:2)
对于它的价值,我在使用面向对象设计之前已经做过这类事情。这是您设计的高级可能性:
ProtocolParser
上课:
SerialPort
对象或等效对象,并侦听传入的字节OnByteReceived
,Unknown
实现特定于协议的状态机(状态为Stx1Received
,Stx2Received
,CkSumReceived
,...,{{1 }})。Packet
类型的对象,该对象在其构造函数中接受一个字节列表。然后它会引发一个事件PacketReceived
,并将Packet
作为参数传递。BadDataReceived
并传递错误数据(可能是为了记录/调试目的)。 Packet
上课:
Command
和Data
属性。上述类足以实现接收协议。您应该能够通过模拟SerialPort类来测试它(即,ProtocolParser
实际上可以使用IDataSource
而不是SerialPort
。)
然后,您可以添加更高级别的类来实现特定于设备的功能,这些功能可以收听PacketReceived
的{{1}}事件。
答案 1 :(得分:1)
当然最好使用OOP设计 根据你的解释,我至少要上两节课:
消息
执行器
该消息将从设备接收命令,Executer将处理该消息。
Message对象将以设备的答案启动。它会解析它,按照你的描述保持字段:
STX
COMMAND
数据
CHKSUM
ETX
然后Executer对象将接收Message对象并执行消息的实际执行,并保存逻辑代码。
答案 2 :(得分:1)
我会比Yochai的答案更进一步,并创建以下类:
通过制作中间表示对象(Message),您可以分离您正在执行的各种操作。例如,如果Powers That Be决定可以将消息文本作为XML或JSON发送,则可以创建不同的MessageParser类,而不必弄乱决定如何处理消息的逻辑。
这也使得单元测试变得更加容易,因为您可以独立于执行程序测试消息解析器。首先通过调用解析函数并检查生成的Message对象来测试消息解析器。然后通过创建Message对象并确保采取适当的操作来测试执行程序。