哪种类型的 UML 图适合描述通过通道协作的 goroutines?
Which type of UML diagram is suited for depicting goroutines collaborating via channel?
假设有一个简单的整数计算器,只支持加法和乘法运算。它将接收一个整数生成器和一个作为加法器或乘数的整数作为其输入参数,并对来自生成器的每个元素应用相应的计算。
我认为以下粗略的时序图恰当地描述了这个逻辑。
但是当我使用 goroutines 和 channels 实现相同的逻辑时,直接的 method/function 调用关系消失了,因为 goroutines 使用 channels 来发送和接收数据。
generator := func(integers ...int) <-chan int {
intStream := make(chan int)
go func() {
defer close(intStream)
for _, i := range integers {
intStream <- i
}
}()
return intStream
}
multiply := func(intStream <-chan int, multiplier int) <-chan int {
multipliedStream := make(chan int)
go func() {
defer close(multipliedStream)
for i := range intStream {
multipliedStream <- i*multiplier
}
}()
return multipliedStream
}
add := func(intStream <-chan int, additive int) <-chan int {
addedStream := make(chan int)
go func() {
defer close(addedStream)
for i := range intStream {
addedStream <- i+additive
}
}()
return addedStream
}
intStream := generator(1, 2, 3, 4)
pipeline := multiply(add(intStream, 1), 2)
for v := range pipeline {
fmt.Println(v)
}
出生在generator
的goroutine作为生产者发送整数; add
和 multiply
中诞生的 goroutine 既是生产者又是消费者;他们接收整数,处理它们,并将它们放入新的通道中。最后用2个channel把这3个goroutines连接成一个pipeline,但是为了一目了然,我没办法呈现出来。
有没有面向goroutines的UML图?
没有 one-size 适合这个域。这完全取决于您希望在设计中将重点放在何处:
- 如果你想坚持 goroutine 是轻量级线程这一事实,并且在消费的通道(缓冲或不缓冲)上,你可能会对 activity 图感兴趣。 Activity 图表也适用于突出功能设计中的值流(即对象流)。
- 如果你想展示对象(包括仿函数)在特定场景中如何交互,保留序列图,但完成它以展示发生了什么:你至少需要一些消费者和生成者之间的消息(这对应通过通道交换:箭头不仅是函数调用;它们是可以对应于函数调用的消息,也可以对应于其他形式的通信)。如果频道很重要,你甚至可以考虑为它添加一条生活热线:这将解决你表达的大部分问题。
不相关:使用 UML 图可视化记录 low-level 代码,或进行某种可视化编程是完全有效的,但往往创建比代码更难阅读的非常复杂的图表。这可能不是最好的目的。
假设有一个简单的整数计算器,只支持加法和乘法运算。它将接收一个整数生成器和一个作为加法器或乘数的整数作为其输入参数,并对来自生成器的每个元素应用相应的计算。
我认为以下粗略的时序图恰当地描述了这个逻辑。
但是当我使用 goroutines 和 channels 实现相同的逻辑时,直接的 method/function 调用关系消失了,因为 goroutines 使用 channels 来发送和接收数据。
generator := func(integers ...int) <-chan int {
intStream := make(chan int)
go func() {
defer close(intStream)
for _, i := range integers {
intStream <- i
}
}()
return intStream
}
multiply := func(intStream <-chan int, multiplier int) <-chan int {
multipliedStream := make(chan int)
go func() {
defer close(multipliedStream)
for i := range intStream {
multipliedStream <- i*multiplier
}
}()
return multipliedStream
}
add := func(intStream <-chan int, additive int) <-chan int {
addedStream := make(chan int)
go func() {
defer close(addedStream)
for i := range intStream {
addedStream <- i+additive
}
}()
return addedStream
}
intStream := generator(1, 2, 3, 4)
pipeline := multiply(add(intStream, 1), 2)
for v := range pipeline {
fmt.Println(v)
}
出生在generator
的goroutine作为生产者发送整数; add
和 multiply
中诞生的 goroutine 既是生产者又是消费者;他们接收整数,处理它们,并将它们放入新的通道中。最后用2个channel把这3个goroutines连接成一个pipeline,但是为了一目了然,我没办法呈现出来。
有没有面向goroutines的UML图?
没有 one-size 适合这个域。这完全取决于您希望在设计中将重点放在何处:
- 如果你想坚持 goroutine 是轻量级线程这一事实,并且在消费的通道(缓冲或不缓冲)上,你可能会对 activity 图感兴趣。 Activity 图表也适用于突出功能设计中的值流(即对象流)。
- 如果你想展示对象(包括仿函数)在特定场景中如何交互,保留序列图,但完成它以展示发生了什么:你至少需要一些消费者和生成者之间的消息(这对应通过通道交换:箭头不仅是函数调用;它们是可以对应于函数调用的消息,也可以对应于其他形式的通信)。如果频道很重要,你甚至可以考虑为它添加一条生活热线:这将解决你表达的大部分问题。
不相关:使用 UML 图可视化记录 low-level 代码,或进行某种可视化编程是完全有效的,但往往创建比代码更难阅读的非常复杂的图表。这可能不是最好的目的。