如何用 UML 表示通信协议?
How to represent communication protocol in UML?
在我的 UML 模型中,我有一个系统及其相互通信的子组件。例如,我有一台电脑和一个遥控机器人,它们通过蓝牙进行通话。目前在图表中的流程是这样的:
“电脑”触发“遥控车”的“setVelocity()”函数。
在这一点上,我想通过这样说来完善沟通
- 计算机发送“移动”信息
- 速度场设置为 100,方向场设置为 0
- 遥控车通过发送ACK报文确认
- 消息 ID 为“Movement”,序列号为 X。
我该怎么做?
编辑:澄清
通常这是我的图表在没有协议细节的情况下的样子:
但是当我尝试添加消息时,至少有两个问题:
- 似乎计算机首先触发了 setVelocity() 函数,然后顺序地触发了 sendBluetoothMessage(),这不是顺序的。 setVelocity() 的以下内容实际上是其中发生的事情。
- sendBluetoothMessage()其实是Computer的一个函数。但这里属于遥控车。 (还是我错了?)ACK 也一样。
感谢您的回复。你是金子!
通用通信协议
两个设备之间发送移动消息的方式主要有两种:
目标设备上的movement()
操作,带有速度和方向参数。您通常会在序列图中显示交换,并带有从发送方到接收方的调用箭头。 return 消息可以标记为 ACK。
A «signal» Movement
: Signals correspond to event messages. In a class diagram, they are represented like a class but with the «signal»
keyword: velocity
and direction
would be attributes of that signal. ACK
would be another signal. The classes that are able to receive the signals show it as reception(看起来像一个操作,但同样带有 «signal» 关键字)。
在这两种情况下,您将使用几乎相同的序列图来显示通信协议的交互。但是信号是用于异步通信的,并且更好地反映了通信的本质。它的语义更适合您的需求。
如果您更喜欢 communication diagram 而不是交互图,信号方法会更清晰,因为通信图不显示 return 消息。
为什么信号是您所需要的(您的编辑)
有了图表,你编辑的问题就更清楚了。我对信号使用的立场没有改变:信号对应于计算机和汽车之间交换的信息。因此,在 class 图表中,您可以将 «signal»Movement
记录为具有属性 id
、velocity
和 direction
:
在您的序列图中,您将使用 Movement (X,100,0)
发送和箭头。 Signal 允许显示协议交换的高级视图,而不会丢失实际的实现细节:
然后可以在单独的图表中显示实施细节。肯定有好几个class在电脑这边(一张图,最后的动作是某种发送)和汽车这边(另一张图:如何接收和发送消息,以及解码其内容)。我不提供示例,因为它看起来很像您当前的图表,但发送功能可能由通信控制器实现。
如果您尝试将协议及其实现放在同一个图中,如在您的第二个图中,由于缺乏关注点分离,它会变得混乱:这里您说计算机正在调用发送函数车,这根本不是你想要的。 reader 很难看到协议真正需要什么,以及实现细节是什么。比如,根据你的图,我还不知道setVelocity
是直接给车发东西,还是在准备阶段用速度发送运动信息。
最后但并非最不重要的一点是,请记住序列图仅代表特定场景。如果您想在 UML 中正式定义一个协议,您还需要创建一个协议状态机来告知消息的有效继承。当你使用信号时,你可以直接使用它们的名字作为状态转换trigger/event.
我遇到了同样的问题。我在网上搜索,找不到我喜欢的东西。因此我想出了这个解决方案。
我在时序图上显示了通信端口,并在端口线之间绘制了通信相关步骤。
这是一个屏幕截图:我对你的问题的看法。
注意:我之前没有使用过蓝牙,所以我不确定确认步骤。如果这是硬件自动完成的(就像在 CAN 总线中),我就不会这样画了。我可能不会显示它或者我不会添加函数 acknowledge();并在蓝牙端口生命线之间画一条线。
如果你真的想在序列图中显示这个级别的细节,它看起来像这样:
备注:
- 对于异步调用,使用空心箭头。
- 使用堆积条表示调用堆栈。
- 在操作的参数列表中,写入“argumentName=argumentValue”或仅写入“argumentValue”。
- 对于确切操作名称未知或不相关的消息,我只使用没有参数列表的描述。
但要注意要显示的细节级别。如果显示调用堆栈中的每个操作,序列图通常会变得过于复杂。
在我的 UML 模型中,我有一个系统及其相互通信的子组件。例如,我有一台电脑和一个遥控机器人,它们通过蓝牙进行通话。目前在图表中的流程是这样的:
“电脑”触发“遥控车”的“setVelocity()”函数。
在这一点上,我想通过这样说来完善沟通
- 计算机发送“移动”信息
- 速度场设置为 100,方向场设置为 0
- 遥控车通过发送ACK报文确认
- 消息 ID 为“Movement”,序列号为 X。
我该怎么做?
编辑:澄清
通常这是我的图表在没有协议细节的情况下的样子:
但是当我尝试添加消息时,至少有两个问题:
- 似乎计算机首先触发了 setVelocity() 函数,然后顺序地触发了 sendBluetoothMessage(),这不是顺序的。 setVelocity() 的以下内容实际上是其中发生的事情。
- sendBluetoothMessage()其实是Computer的一个函数。但这里属于遥控车。 (还是我错了?)ACK 也一样。
感谢您的回复。你是金子!
通用通信协议
两个设备之间发送移动消息的方式主要有两种:
目标设备上的
movement()
操作,带有速度和方向参数。您通常会在序列图中显示交换,并带有从发送方到接收方的调用箭头。 return 消息可以标记为 ACK。A
«signal» Movement
: Signals correspond to event messages. In a class diagram, they are represented like a class but with the«signal»
keyword:velocity
anddirection
would be attributes of that signal.ACK
would be another signal. The classes that are able to receive the signals show it as reception(看起来像一个操作,但同样带有 «signal» 关键字)。
在这两种情况下,您将使用几乎相同的序列图来显示通信协议的交互。但是信号是用于异步通信的,并且更好地反映了通信的本质。它的语义更适合您的需求。
如果您更喜欢 communication diagram 而不是交互图,信号方法会更清晰,因为通信图不显示 return 消息。
为什么信号是您所需要的(您的编辑)
有了图表,你编辑的问题就更清楚了。我对信号使用的立场没有改变:信号对应于计算机和汽车之间交换的信息。因此,在 class 图表中,您可以将 «signal»Movement
记录为具有属性 id
、velocity
和 direction
:
在您的序列图中,您将使用 Movement (X,100,0)
发送和箭头。 Signal 允许显示协议交换的高级视图,而不会丢失实际的实现细节:
然后可以在单独的图表中显示实施细节。肯定有好几个class在电脑这边(一张图,最后的动作是某种发送)和汽车这边(另一张图:如何接收和发送消息,以及解码其内容)。我不提供示例,因为它看起来很像您当前的图表,但发送功能可能由通信控制器实现。
如果您尝试将协议及其实现放在同一个图中,如在您的第二个图中,由于缺乏关注点分离,它会变得混乱:这里您说计算机正在调用发送函数车,这根本不是你想要的。 reader 很难看到协议真正需要什么,以及实现细节是什么。比如,根据你的图,我还不知道setVelocity
是直接给车发东西,还是在准备阶段用速度发送运动信息。
最后但并非最不重要的一点是,请记住序列图仅代表特定场景。如果您想在 UML 中正式定义一个协议,您还需要创建一个协议状态机来告知消息的有效继承。当你使用信号时,你可以直接使用它们的名字作为状态转换trigger/event.
我遇到了同样的问题。我在网上搜索,找不到我喜欢的东西。因此我想出了这个解决方案。 我在时序图上显示了通信端口,并在端口线之间绘制了通信相关步骤。 这是一个屏幕截图:我对你的问题的看法。
注意:我之前没有使用过蓝牙,所以我不确定确认步骤。如果这是硬件自动完成的(就像在 CAN 总线中),我就不会这样画了。我可能不会显示它或者我不会添加函数 acknowledge();并在蓝牙端口生命线之间画一条线。
如果你真的想在序列图中显示这个级别的细节,它看起来像这样:
备注:
- 对于异步调用,使用空心箭头。
- 使用堆积条表示调用堆栈。
- 在操作的参数列表中,写入“argumentName=argumentValue”或仅写入“argumentValue”。
- 对于确切操作名称未知或不相关的消息,我只使用没有参数列表的描述。
但要注意要显示的细节级别。如果显示调用堆栈中的每个操作,序列图通常会变得过于复杂。