英文:
Which type of UML diagram is suited for depicting goroutines collaborating via channel?
问题
让我们假设有一个简单的整数计算器,它只支持加法和乘法操作。它将接收一个整数生成器和一个整数作为加法或乘法器作为其输入参数,并对来自生成器的每个元素应用相应的计算。
但是当我使用goroutines和channels来实现相同的逻辑时,直接的方法/函数调用关系消失了,因为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既是生产者又是消费者;它们接收整数,处理它们,并将它们放入新的通道中。最后,两个通道将这3个goroutine连接成一个管道,但我不知道如何清晰地展示它。
是否有一种面向goroutine的UML图表?
英文:
Let's assume there is a simple integer calculator that only supports addition and multiplication operation. It will receive an integer generator and an integer as additive or multiplier as its input parameters and apply the corresponding calculation for each element that comes from the generator.
I think the following rough sequence diagram depicts this logic appropriately.
But when I use goroutines and channels to implement the same logic, the straight method/function calling relationship disappeared because goroutines utilize channels to send and receive data.
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)
}
The goroutine born in the generator
acts as a producer to send integers; the goroutines born in the add
and multiply
are both producers and consumers; they receive integers, handle them, and put them into new channels. Finally, two channels connect these 3 goroutines as a pipeline, but I have no idea to present it to be clear at a glance.
Is there a kind of goroutines-oriented UML diagram?
答案1
得分: 2
在这个领域中,没有一种适用于所有情况的方法。一切都取决于你在设计中想要关注的重点:
- 如果你想强调goroutine是轻量级线程以及被消费的通道(有缓冲或无缓冲),你可能会对活动图感兴趣。活动图也适用于突出函数式设计中的值流(即对象流)。
- 如果你想展示对象(包括函数对象)在特定场景中的交互,保留序列图,但完善它以展示发生的情况:你至少需要一些消费者和生成器之间的消息(这对应于通过通道进行的交换:箭头不仅仅是函数调用;它们是可以对应于函数调用,也可以对应于其他形式的通信的消息)。如果通道非常重要,甚至可以考虑为其添加一个生命线:这将解决你所表达的大部分关注点。
与此无关:使用UML图表对低级代码进行视觉文档化或进行某种形式的可视化编程是完全有效的,但往往会创建非常复杂的图表,比代码更难阅读。这可能不是最好的用途。
英文:
There is no one-size fits all in this domain. It all depends where you want to set the focus in your design:
- if you want to insist on the fact that a goroutine is lightweight thread, and on the channel (buffered or not) that is consumed, you may be interested in activity diagrams. Activity diagrams are also suitable to highlight the flow of values (i.e. object flows) in a functional design.
- if you want to show how objects (including functors) interact in a specific scenario, keep the sequence diagram, but complete it to show what happens: you need at least some messages between the consumers and the generator (this corresponds to the exchanges via the channel: arrows are not only function calls; they are messages that can correspond to a function call but also to other forms of communication). If the channel is very important, you may even consider to add a liefline for it: this would address most of your expressed concerns.
Not related: using UML diagrams to visually document low-level code, or do some kind of visual programming is perfectly valid, but tends to create very complex diagrams that are harder to read thant the code. This may not be the best purpose.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论