动态序列图可视化控件

介绍 (Introduction)

Sequence diagrams are one of the fundamental types of UML diagrams. Their focus is in modelling the dynamics of a system. They allow describing interactions between the system and the actors of its environment or between the participants of the system over time. Their clear graphical layout helps give a quick intuitive understanding of the system’s behavior.

序列图是UML图的基本类型之一。 他们的重点是对系统动力学进行建模。 它们允许描述系统与环境参与者之间或系统参与者之间随时间的相互作用。 它们清晰的图形布局有助于快速直观地了解系统的行为。

This article presents a Windows .NET control for dynamic visualization of objects and their interactions as sequence diagrams. The control incorporates break functionality similar to a debugger's. In addition, it provides a practical-use sample in which an application's execution is intercepted and visualized in real time.

本文介绍了一个Windows .NET控件,用于动态可视化对象及其相互作用(作为序列图)。 该控件具有类似于调试器的中断功能。 此外,它提供了一个实际使用的示例,其中实时拦截和可视化了应用程序的执行。

Image 1

为什么要使用它? (Why Use It?)

Here are two scenarios in which the control would be of use:

这是使用控件的两种情况:

分布式系统的端到端跟踪 (End-To-End Tracing of a Distributed System)

You have a distributed application composed of separate components (such as microservices) residing on different computers, and you have difficulty tracing the entire execution. You forward the log events of every microservice to a collector, so that you can visualize the entire flow in a single sequence diagram for easier analysis and debugging:

您有一个分布在不同计算机上的,由独立组件(例如微服务)组成的分布式应用程序,很难跟踪整个执行过程。 您可以将每个微服务的日志事件转发给收集器,以便可以在单个序列图中可视化整个流程,以便于分析和调试:

Image 2

The control has originally been created for this scenario, and forms a part of it. It is repackaged for generic use.

该控件最初是为此场景创建的,并构成其一部分。 将其重新打包以用于常规用途。

调试器 (Debugger)

You have developed a software tool that intercepts method calls of any .NET application by using AOP (Aspect Oriented Programming) techniques, and now you want to visualize the captured call trace as a process graph:

您已经开发了一种软件工具,可以使用AOP(面向方面​​的编程)技术来拦截任何.NET应用程序的方法调用,现在您希望将捕获的调用跟踪可视化为流程图:

Image 3

Near the end of the article, I provide a proof of concept for this type of usage.

在本文结尾处 ,我提供了这种用法的概念证明。

背景 (Background)

Sequence diagrams show the behavior of objects. As a result, the concept of time, as well as dependencies between objects, appears in sequence diagrams. This, in turn, enables sequence diagrams to show “what happens” in the system.

顺序图显示了对象的行为。 结果,时间的概念以及对象之间的依存关系出现在序列图中。 反过来,这使序列图可以显示系统中的“情况”。

Most existing use of sequence diagrams is limited to static models: The diagram is based to a definition of a model, or a static code. They behave as blueprints of a process and serve for communicating the interaction within the system.

序列图的大多数现有用法仅限于静态模型:序列图基于模型或静态代码的定义。 它们充当流程的蓝图,并用于在系统内进行交互。

But sequence diagrams can also be used for visualizing real-time activity of a system. This activity may be the live method calls in a computer program, the communication within the components of a distributed application and so on. Dynamic analysis differs from static analysis is that it requires an active system to model. That is, dynamic analysis is performed on a running system, whereas static analysis is performed on system artifacts (e.g., source code).

但是,时序图也可以用于可视化系统的实时活动。 此活动可能是计算机程序中的实时方法调用,分布式应用程序的组件内的通信等等。 动态分析与静态分析的不同之处在于,它需要一个活动的系统进行建模。 即,在运行的系统上执行动态分析,而在系统工件(例如源代码)上执行静态分析。

使用代码 (Using the Code)

样品 (Samples)

The SequenceDiagram solution contains two projects: SequenceDiagramLib has the actual control whereas the SequenceDiagramTestApp project has various examples demonstrating the capabilities of the control.

SequenceDiagram解决方案包含两个项目: SequenceDiagramLib具有实际控件,而SequenceDiagramTestApp项目具有各种示例,这些示例演示了控件的功能。

Image 4

All but one of the samples run entirely in the main thread. 'The Basic example (Threaded)' sample at the bottom is included for situations in which the sequence is modified in a different thread.

除了一个样本外,所有样本都完全在主线程中运行。 底部包含“基本示例(线程)”示例,用于在不同线程中修改序列的情况。

Below is a simple sequence diagram definition involving two participants and some messaging between them:

下面是一个简单的时序图定义,涉及两个参与者以及他们之间的一些消息传递:

Sequence sequence = this.sequenceControl.Sequence;

Participant alice = sequence.Participants.Create("Alice");
Participant bob = sequence.Participants.Create("Bob");
sequence.Messages.Add("AuthenticationRequest", alice, bob);
sequence.Tick();

sequence.Messages.Add("AuthenticationResponse", bob, alice, dashStyle: DashStyle.Dash);
sequence.Tick();

sequence.Messages.Add("Another authentication request", alice, bob);
sequence.Tick();

sequence.Messages.Add("Another authentication Response", bob, alice);
sequence.Tick();

This sequence is rendered by the SequenceDiagramControl as:

该序列由SequenceDiagramControl呈现为:

Image 5

The control represents the passage of time by a horizontal line. Each horizontal line represents a timetick whereas the current timetick is represented as a red line.

控件用水平线表示时间的流逝。 每条水平线表示一个时间刻度,而当前时间标记则表示为红线。

A second, more complex sequence diagram definition of our SequenceDiagramControl:

我们的SequenceDiagramControl第二个更复杂的序列图定义:

Sequence sequence = this.sequenceControl.Sequence;

Participant user = sequence.Participants.Create("User");
Participant a = sequence.Participants.Create("A");
Participant b = sequence.Participants.Create("B");
Participant c = sequence.Participants.Create("C");
sequence.Messages.Add("DoWork", user, a);
a.Activate();
sequence.Tick();

sequence.Messages.Add("<< createRequest >>", a, b);
b.Activate();
sequence.Tick();

sequence.Messages.Add("DoWork", b, c);
c.Activate();
sequence.Tick();

sequence.Messages.Add("WorkDone", c, b, dashStyle: DashStyle.Dot);
c.Deactivate();
c.Destroy();
sequence.Tick();

sequence.Messages.Add("RequestCreated", b, a, dashStyle: DashStyle.Dot);
b.Deactivate();
sequence.Tick();

sequence.Messages.Add("Done", a, user);
a.Deactivate();
sequence.Tick();

...and the SequenceDiagramControl's rendition:

...以及SequenceDiagramControl的呈现形式:

Image 6

如何使用控件 (How To Use the Control)

  1. Create a Windows form named Form1.

    创建一个名为Form1的Windows窗体。

  2. Add a SequenceDiagramControl named sequenceDiagram to your form.

    向您的窗体添加一个名为sequenceDiagramSequenceDiagramControl

  3. Add two buttons to your form. Name them runButton and continueButton.

    将两个按钮添加到您的窗体。 将它们命名为runButtoncontinueButton

  4. Set the handlers for the two buttons.

    设置两个按钮的处理程序。

    The event handler for the runButton creates a sequence with two participants and two timesteps:

    runButton的事件处理程序创建一个包含两个参与者和两个时间步长的序列:

    private void runButton_Click(object sender, EventArgs e)
    {
        Sequence sequence = this.sequenceDiagram.Sequence;
    
        Participant a = sequence.Participants.CreateOrGet("A");
        Participant b = sequence.Participants.CreateOrGet("B");
        sequence.Messages.Add("Create request", a, b);
        sequence.Tick();
    
        sequence.Messages.Add("Return", b, a);
        sequence.Tick();
    }
    
    	

    The event handler for the continueButton is available when the sequence is in wait state. Its function is to resume the execution of the application.

    当序列处于等待状态时, continueButton的事件处理程序可用。 它的功能是恢复应用程序的执行。

    private void continueButton_Click(object sender, EventArgs e)
    {
        Sequence sequence = this.sequenceDiagram.Sequence;
        sequence.Continue();
    }
    	
  5. Define the OnEnter() and OnExit() event handlers of the sequence.

    定义序列的OnEnter()OnExit()事件处理程序。

    The sequence calls the OnEnterBreak() event handler at the beginning of a break, and it calls the OnExitBreak() event handler when the execution is about to resume.

    该序列在OnEnterBreak()开始时调用OnExitBreak()事件处理程序,并在要恢复执行时调用OnExitBreak()事件处理程序。

    private void Sequence_OnEnterBreak()
    {
        this.runButton.Enabled = false;
        this.continueButton.Enabled = true;
    }
    
    private void Sequence_OnExitBreak()
    {
        this.runButton.Enabled = true;
        this.continueButton.Enabled = false;
    }
    	
  6. The constructor of the form initializes the enabled/disabled states of the two buttons and sets the sequence event handlers.

    窗体的构造函数初始化两个按钮的启用/禁用状态,并设置序列事件处理程序。

    public Form1()
    {
        InitializeComponent();
    
        this.runButton.Enabled = true;
        this.continueButton.Enabled = false;
    
        Sequence sequence = this.sequenceDiagram.Sequence;
        sequence.OnEnterBreak += Sequence_OnEnterBreak;
        sequence.OnExitBreak += Sequence_OnExitBreak;
    }
    	

这个怎么运作 (How It Works)

The control contains a reference to the Sequence class which encapsulates the entire information of a sequence. Elements such as participants, activations, messages, timesteps are stored in this class's instances.

该控件包含对Sequence类的引用,该类封装了序列的全部信息。 诸如参与者,激活,消息,时间步之类的元素存储在此类的实例中。

Tick()方法 (Tick() Method)

Events that take place within the same timeframe are added to the sequence in an arbitrary order. sequence.Tick() calls are of special importance: It is at these calls that:

在同一时间范围内发生的事件将以任意顺序添加到序列中。 sequence.Tick()调用特别重要:正是在这些调用中:

  1. A break event takes place and the SequenceDiagramControl seizes program execution until the user takes action to resume.

    发生中断事件, SequenceDiagramControl抓住程序执行,直到用户采取措施继续执行。

  2. The logical clock of the sequence is incremented by 1.

    序列的逻辑时钟加1

    Image 7

The implementation details of the breakpoint functionality is as follows:

断点功能的实现细节如下:

  1. Whenever a sequence.Tick() method is called, the underlying Sequence object calls its registered OnEnterBreak() handler. This enables its parent form for tasks such as enabling its continueButton.

    每当调用sequence.Tick()方法时,底层的Sequence对象都会调用其已注册的OnEnterBreak()处理程序。 这将启用其父表单以执行诸如启用continueButton任务。

  2. The sequence stays in wait state with this method:

    使用以下方法,序列保持等待状态:

    private void ResponsiveWait()
    {
        this.wait = true;
    
        for (;;)
        {
            if (!this.wait)
                break;
    
            if (this.exit)
                break;
    
            System.Windows.Forms.Application.DoEvents();
                System.Threading.Thread.Sleep(200);
        }
    }
    	

The Application.DoEvent() enables seizing execution flow without blocking itself or the application it resides in. The use of Application.DoEvents() is discouraged in favor of other techniques such as threads. But for this project's needs (such as minimal interference with the debugged application), I found it to be the most suitable method.

Application.DoEvent()能够抓住执行流,而不会阻塞自身或驻留在其中的Application.DoEvents()不建议使用Application.DoEvents()来支持其他技术,例如线程。 但是针对该项目的需求(例如对调试后的应用程序的干扰最小),我发现它是最合适的方法。

  1. When the user clicks the continueButton, sequence.Continue() method is called and wait state ends.

    当用户单击continueButton ,将调用sequence.Continue()方法,并且等待状态结束。

  2. The sequence class calls the registered OnExitBreak() event handler. This enables its parent form for tasks such as disabling its continueButton, as execution resumes until the next break.

    序列类调用已注册的OnExitBreak()事件处理程序。 随着执行恢复到下一个中​​断,这将使其父窗体能够执行诸如禁用其continueButton任务。

元素渲染 (Rendition of Elements)

The visual rendition of elements take place in SequenceDiagramControl class. Each UML element has a method and a reference point variable named p0.

元素的可视化呈现在SequenceDiagramControl类中。 每个UML元素都有一个方法和一个名为p0的参考点变量。

API参考 (API Reference)

Image 8

Image 9

The Sequence class is the base object of the data model of the SequenceDiagramControl. All information about the sequence is stored in this class. It has collections of available participants, activations, messages and boxes.

Sequence类是的数据模型的基础对象SequenceDiagramControl 。 有关序列的所有信息都存储在此类中。 它具有可用参与者,激活,消息和框的集合。

Boxes are optional elements for grouping related participants.

Box是用于对相关参与者进行分组的可选元素。

Participants own a collection of activations, and each activation has a collection of name/value pairs called tags. Participants communicate with each via Messages.

Participant拥有一个激活集合,每个激活都有一个称为标签的名称/值对集合。 参与者通过Message与每个人进行交流。

序列 (Sequence)

The Sequence class encapsulates the entire data within the sequence. It focuses on time sequencing or time ordering of messages between participants and the order in which messages are sent. The emphasis in the sequence is what happens first, second, and so on.

Sequence类将整个数据封装在序列中。 它着重于参与者之间消息的时间顺序或时间顺序以及消息的发送顺序。 顺序中的重点是首先发生的事情,然后发生第二件事,依此类推。

API用法 (API Usage)


sequence.Clear();

sequence.Clear();

Clears the current state and all members of the sequence. The sequence returns to its initial state.

清除当前状态和序列的所有成员。 序列返回到其初始状态。



sequence.Tick();

sequence.Tick();

The focus of the sequence diagram is to visualize a system's change and the communication of the elements over time. Whereas the x-axis displays the members of sequence (called participants), y-axis represents time.

时序图的重点是可视化系统的变化以及随时间推移的元素通信。 x轴显示序列的成员(称为参与者),而y轴表示时间。

In the SequenceDiagramControl model, the timeticks are represented as discrete values. Whenever a time tick occurs, the sequence advances to the next timestep value. The time tick is the point where a break occurs in which the user can respond to.

SequenceDiagramControl模型中,时间标记表示为离散值。 每当出现时间刻度时,序列都会前进到下一个时间步长值。 时间刻度是用户可以做出响应的中断点。



参加者 (Participants)

Participants are representatives or objects that take part in the sequence. They are usually placed across the top of the diagram. The participant is typically represented as a rectangle, and its name is placed inside the box. Per the UML specification, this name can be underlined meaning the participant represents a specific instance of a class in a sequence diagram. Additional information such as UML stereotypes can be included within the participant rectangle as well.

参与者是参与序列的代表或对象。 它们通常放在图的顶部。 参与者通常以矩形表示,其名称放在框中。 根据UML规范,此名称可以带下划线,表示参与者在序列图中表示类的特定实例。 参与者矩形内也可以包含其他信息,例如UML构造型。

Lifeline of the participant is displayed as a vertical dashed line beginning from the bottom of the participant. They represent the life and interactions of the participant over time.

参与者的生命线从参与者的底部开始显示为垂直虚线。 它们代表了参与者随着时间的生活和互动。

Image 10
Participant foo1 = sequence.Participants.Create("Foo1", type: EParticipantType.Actor);
Participant foo2 = sequence.Participants.Create("Foo2", type: EParticipantType.Boundary);
Participant foo3 = sequence.Participants.Create("Foo3", type: EParticipantType.Control);
Participant foo4 = sequence.Participants.Create("Foo4", type: EParticipantType.Entity);
Participant foo5 = sequence.Participants.Create("Foo5", type: EParticipantType.Database);
Participant foo6 = sequence.Participants.Create("Foo6", type: EParticipantType.Collections);
sequence.Messages.Add("To boundary", foo1, foo2);
sequence.Tick();

sequence.Messages.Add("To control", foo1, foo3);
sequence.Tick();

sequence.Messages.Add("To entity", foo1, foo4);
sequence.Tick();

sequence.Messages.Add("To database", foo1, foo5);
sequence.Tick();

sequence.Messages.Add("To collections", foo1, foo6);
sequence.Tick();

API用法 (API Usage)
Participant participant = sequence.Participants.Create(string name, bool underlined = false, 
Color? color = null, Color? textColor = null, EParticipantType? type = null, Box box = null, 
bool createNow = false);

It creates a new participant and places it within the sequence. The call fails if the sequence already has a participant with the specified name.

它创建一个新的参与者并将其放置在序列中。 如果序列中已有指定名称的参与者,则呼叫失败。

  • name: Name of the participant.

    name :参与者的名称。

  • underlined: Whether the name of the participant will be displayed as underlined text. Underlined text in UML represents a specific instance of a class.

    underlined :参与者的姓名是否将显示为带下划线的文本。 UML中带下划线的文本表示类的特定实例。

  • color: Background color of the participant.

    color :参与者的背景色。

  • textColor: Text color of the participant.

    textColor :参与者的文本颜色。

  • type: Type of participant. It affects how the participant is displayed (Box, Boundary, Control, Entity, Database, Collection).

    type :参与者的类型。 它影响参与者的显示方式(框,边界,控件,实体,数据库,集合)。

  • box: The box which participant belongs to. This value may be null.

    box :参与者所属的盒子。 该值可以为null

  • createNow: This value is usually omitted, resulting in the participant being placed at the top of the diagram. Setting this value emphasizes that the participant is being created and its lifetime starts at the current timestep.

    createNow :通常会省略此值,从而将参与者置于图的顶部。 设置此值将强调正在创建参与者,并且其生存期将从当前时间步开始。



Participant participant = sequence.Participants.CreateOrGet
(string name, bool underlined = false, Color? color = null, Color? textColor = null, 
EParticipantType? type = null, Box box = null, bool createNow = false);

If a participant with the given name exists, it returns it.

如果存在具有给定名称的参与者,则将其返回。

If a participant with the given name does not exist, it creates a new participant, places it within the sequence, and returns it.

如果不存在具有给定名称的参与者,它将创建一个新参与者,将其放置在序列中,然后返回。

  • name: Name of the participant.

    name :参与者的名称。

  • underlined: Whether the name of the participant will be displayed as underlined text. Underlined text in UML diagrams represents a specific instance of a class.

    underlined :参与者的姓名是否将显示为带下划线的文本。 UML图中带下划线的文本表示类的特定实例。

  • color: Background color of the participant.

    color :参与者的背景色。

  • textColor: Text color of the participant.

    textColor :参与者的文本颜色。

  • type: Type of participant. It affects how the participant is displayed (Box, Boundary, Control, Entity, Database, Collection).

    type :参与者的类型。 它影响参与者的显示方式(框,边界,控件,实体,数据库,集合)。

  • box: The box which participant belongs to. This value may be null.

    box :参与者所属的盒子。 该值可以为null

  • createNow: Omitting this value, resulting the participant to be placed at the top of the diagram. Setting this value emphasizes that the participant is being created and its lifetime starts at the current timestep.

    createNow :忽略此值,导致参与者被放置在图的顶部。 设置此值将强调正在创建参与者,并且其生存期将从当前时间步开始。



Participant participant = sequence.Participants[name];

It returns the participant with the given name. The call fails if a participant with the given name does not exist.

它返回给定名称的参与者。 如果不存在具有给定名称的参与者,则呼叫失败。

  • name: Name of the participant.

    name :参与者的名称。



participant.Destroy();

Ends the current activation of the participant.

结束参与者的当前激活。



留言内容 (Messages)

Messages represent the information transmitted between two participants. It is possible that a participant can send a message to itself. Messages can be synchronous or asynchronous, they may reflect the start and execution of an operation or the sending and reception of a signal.

消息代表两个参与者之间传输的信息。 参与者可能会向自己发送消息。 消息可以是同步或异步的,它们可以反映操作的开始和执行或信号的发送和接收。

Image 11
Participant bob = sequence.Participants.Create("Bob");
Participant alice = sequence.Participants.Create("Alice");
sequence.Messages.Add("hello", bob, alice, color: Color.Red);
sequence.Tick();

sequence.Messages.Add("ok", alice, bob, color: Color.Blue);
sequence.Tick();

Participant alice = sequence.Participants.Create("Alice");
sequence.Messages.Add("signal to self", alice);
sequence.Tick();

API用法 (API Usage)
Message message = sequence.Messages.Add(string name, Participant from, 
Participant to, Color? color = null, DashStyle? dashStyle = null);

Creates a new message between a source and a destination participant.

在源参与者和目标参与者之间创建新消息。

  • name: Name of the message.

    name :消息名称。

  • from: The source participant of the message.

    from :消息的源参与者。

  • to: The target participant of the message.

    to :消息的目标参与者。

  • color: The color the message is rendered.

    color :消息呈现的颜色。

  • arrowHead: Arrow head of the message. Different arrow heads represent different types of messages.

    arrowHead :消息的箭头。 不同的箭头代表不同类型的消息。

  • dashStyle: Dash style of the message line. Different dash styles represent different types of messages.

    dashStyle :消息行的短划线样式。 不同的破折号样式表示不同类型的消息。



Message message = sequence.Messages.Add(string name, Participant self, 
Color? color = null, DashStyle? dashStyle = null);

Creates a new self-message. The participant sends a message to itself.

创建一个新的自消息。 参与者向自己发送一条消息。

  • name: Name of the message.

    name :消息名称。

  • self: The owner participant of the message.

    self :消息的所有者参与者。

  • color: The color the message is rendered.

    color :消息呈现的颜色。

  • arrowHead: Arrow head of the message. Different arrow heads represent different types of messages.

    arrowHead :消息的箭头。 不同的箭头代表不同类型的消息。

  • dashStyle: Dash style of the message line. Different dash styles represent different types of messages.

    dashStyle :消息行的短划线样式。 不同的破折号样式表示不同类型的消息。

激活方式 (Activations)

Activations (also called Focus of control elements/Execution occurrences) are the period during which a participant is performing an operation. The time an object is busy executing a process or waiting for a reply is represented as a rectangle placed vertically on its lifeline. The top and the bottom of the rectangle are aligned with the initiation and the completion time respectively. Activations can be recursive.

激活(也称为控制元素/执行焦点)是参与者执行操作的时间段。 对象忙于执行过程或等待回复的时间表示为垂直放置在其生命线上的矩形。 矩形的顶部和底部分别与开始时间和完成时间对齐。 激活可以是递归的。

Image 12
Participant user = this.sequence.Participants.Create("User");
Participant a = this.sequence.Participants.Create("A");
Participant b = this.sequence.Participants.Create("B");
sequence.Messages.Add("DoWork", user, a);
a.Activate(color: Color.FromArgb(0xff, 0xbb, 0xbb));
sequence.Tick();

sequence.Messages.Add("Internal call", a);
a.Activate(color: Color.DarkSalmon);
sequence.Tick();

sequence.Messages.Add("<< createRequest >>", a, b);
b.Activate();
sequence.Tick();

sequence.Messages.Add("RequestCreated", b, a, dashStyle: DashStyle.Dash);
b.Deactivate();
a.Deactivate();
sequence.Tick();

sequence.Messages.Add("Done", a, user);
a.Deactivate();
sequence.Tick();

API用法 (API Usage)
participant.Activate(string name = null, Color? color = null);

Initiates an activation for a participant. The activations can be recursive.

为参与者启动激活。 激活可以是递归的。

  • name: Name of the activation.

    name :激活名称。

  • color: Background color of the activation.

    color :激活的背景色。



participant.Deactive();

Deactivates the current activation of the participant.

停用参与者的当前激活。



盒子 (Boxes)

Boxes help organize a sequence diagram. Interrelated participants can be grouped within a box.

方框有助于组织顺序图。 相互关联的参与者可以分组在一个框中。

Image 13
Box box = sequence.Boxes.Create("Internal Service");
box.Color = Color.LightBlue;
Participant bob = sequence.Participants.Create("bob", box: box);
Participant alice = sequence.Participants.Create("alice", box: box);
Participant other = sequence.Participants.Create("other");
sequence.Messages.Add("hello", bob, alice);
sequence.Tick();

sequence.Messages.Add("hello", alice, other);
sequence.Tick();

API用法 (API Usage)
Box box = sequence.Boxes.Create(string name, Color? color = null);

It creates a new box and places it within the sequence. The call fails if the sequence already has a box with the specified name.

它创建一个新框并将其放置在序列中。 如果序列中已经有一个具有指定名称的框,则调用将失败。

  • name: Name of box.

    name :盒子名称。

  • color: Background color of the box.

    color :盒子的背景色。



Box box = sequence.Boxes.CreateOrGet(string name, Color? color = null);

If a participant with the given name exists, it returns it.

如果存在具有给定名称的参与者,则将其返回。

If a participant with the given name does not exist, it creates a new participant, places it within the sequence, and returns it.

如果不存在具有给定名称的参与者,它将创建一个新参与者,将其放置在序列中,然后返回。

  • name: Name of box.

    name :盒子名称。

  • color: Background color of the box.

    color :盒子的背景色。



Box box = sequence.Boxes[name];

It returns the box with the given name. The call fails if a box with the given name does not exist.

它返回具有给定名称的框。 如果不存在具有给定名称的框,则调用失败。

  • name: Name of the participant.

    name :参与者的名称。

()

SequenceDiagramControl + AOP库=调试器 (SequenceDiagramControl+AOP Library=A Debugger)

Image 14

SequenceDiagramDebugger is not a part of the SequenceDiagramControl. Rather, it is an extension for demonstrating a concrete, real-life use of the SequenceDiagramControl. In addition to this, there is a persistent criticism for existing AOP (Aspect Oriented Programming) samples is that nearly all of them involve either logging or access control of method calls. In this case, AOP is used for an alternative need: execution visualization.

SequenceDiagramDebugger不是一部分SequenceDiagramControl 。 而是,它是演示SequenceDiagramControl具体实际使用的扩展。 除此之外,对于现有的AOP(面向方面​​编程)样本一直存在一种批评,即几乎所有样本都涉及方法调用的日志记录或访问控制。 在这种情况下,AOP用于替代需求:执行可视化。

The debugger sample serves as a proof of concept and has limitations such as supporting applications using a single thread only.

调试器样本用作概念证明,并具有局限性,例如仅支持使用单个线程的应用程序。

AOP enables intercepting methods of an application. These intercepted method calls are then visualized by the SequenceDiagramControl. With the control's additional built-in break functionality, this enables debugging an application's execution flow.

AOP启用应用程序的拦截方法。 然后,通过SequenceDiagramControl可视化这些拦截的方法调用。 使用控件的附加内置中断功能,可以调试应用程序的执行流程。

The mapping is between the application and sequence diagram elements is implemented as follows:

在应用程序和顺序图元素之间的映射如下实现:

  • Application -> Sequence

    应用->顺序
  • Application class -> Participant

    申请类别->参加者
  • Class method duration -> Activation

    类方法持续时间->激活
  • Method call -> Message

    方法调用->消息

An important objective is to enable debugging with minimal change to the host application. This is accomplished by adding a single line of code to the debugged application so that our tool integrates with it:

一个重要的目标是启用调试程序,而对主机应用程序的更改最少。 这是通过向调试后的应用程序添加一行代码来实现的,以便我们的工具与其集成在一起:

public MainForm()
{
    InitializeComponent();

    SequenceDiagramDebugger.Init(this, "TestApp.");
}

SequenceDiagramDebugger.Init(this, "TestApp"); serves two purposes:

SequenceDiagramDebugger.Init(this, "TestApp"); 有两个目的:

  1. It weaves all methods of the debugged application in the "TestApp" namespace.

    它在“ TestApp ”命名空间中编织了调试应用程序的所有方法。

  2. It opens our DebuggerForm, which contains a SequenceDiagramControl.

    它将打开我们的DebuggerForm ,其中包含SequenceDiagramControl

During execution, the AOP library informs us of every relevant occurrence of method entries and exits via advisors. These intercepted method entries and exits are then visualized in our SequenceDiagramControl based SequenceDiagramDebugger.

在执行期间,AOP库通过顾问程序通知我们方法入口和出口的每一次相关事件。 这些截获的方法的入口和出口,然后在我们的可视化SequenceDiagramControl基于SequenceDiagramDebugger

In the example, you click the 'Calculate' button of the TestApp once, and then the 'Continue' of the DebuggerForm until the end of the execution.

在示例中,您单击一次TestApp的“ 计算 ”按钮,然后单击DebuggerForm的“ 继续 ”,直到执行结束。

Image 15

兴趣点 (Points of Interest)

序列图功能未实现 (Sequence Diagram Features Not Implemented)

Some parts of the UML sequence diagram specification (such as the elements for representing loops, branches, and alternative execution flows) are meaningful only when the diagram is used for documenting the flow of a process. These features are omitted in the SequenceDiagramControl, as the control's focus is the dynamic visualization of what has already taken place, not what may be.

UML序列图规范的某些部分(例如表示循环,分支和替代执行流的元素)仅在该图用于记录流程流时才有意义。 这些功能在SequenceDiagramControl被省略,因为控件的焦点是动态可视化已发生的事情,而不是可能发生的事情。

植物UML (PlantUML)

PlantUML is an open-source tool that aids in creating various types of UML and non-UML diagrams from text files conforming to its diagram definition syntaxes. You specify your UML diagram definition in the tool's text format and unlike SequenceDiagramControl, it creates a static image representation of the diagram. It has support for sequence, use-case, class, activity, component, state, object, deployment, and timing UML diagrams, as well as numerous non-UML ones.

PlantUML是一种开放源代码工具,可帮助从符合其图定义语法的文本文件中创建各种类型的UML和非UML图。 您可以以工具的文本格式指定UML图表定义,并且与SequenceDiagramControl不同,它可以创建图表的静态图像表示形式。 它支持序列,用例,类,活动,组件,状态,对象,部署和定时UML图,以及许多非UML图。

I have long been using PlantUML tool for technical documentation, and I have been impressed by its easy to use terminology. So one of my design objectives has been to follow PlantUML's naming of elements as closely as possible, and compare PlantUML's and SequenceDiagramControl's renditions of the same sequence. All features samples I have provided have a corresponding one in the PlantUml tool sequence diagram creation page.

长期以来,我一直在使用PlantUML工具来获取技术文档,其易于使用的术语给我留下了深刻的印象。 因此,我的设计目标之一是尽可能地遵循PlantUML的元素命名,并比较相同序列的PlantUML和SequenceDiagramControl的表示形式。 我提供的所有功能样本在PlantUml工具序列图创建页面中都有一个对应的样本。

In this section, I provide the PlantUML text definition equivalents and their outputs of the two features samples I have described at the beginning of the article, so you can compare their similarities and differences:

在本节中,我提供了PlantUML文本定义等效项以及我在本文开头描述的两个功能样本的输出,因此您可以比较它们的异同:

The PlantUML text definition equivalent of the first feature sample:

第一个功能样本等效的PlantUML文本定义:

@startuml
Alice -> Bob: Authentication Request
Bob --> Alice: Authentication Response

Alice -> Bob: Another authentication Request
Alice <-- Bob: Another authentication Response
@enduml

When you feed this text to the PlantUML parser, you get the following (static) sequence diagram:

当将此文本输入到PlantUML解析器时,您将获得以下(静态)序列图:

Image 16

And this is the PlantUML equivalent of the second features sample I have described above.

这与我上面描述的第二个特征样本的PlantUML等效。

@startuml
participant User

User -> A: DoWork
activate A

A -> B: << createRequest >>
activate B

B -> C: DoWork
activate C
C --> B: WorkDone
destroy C

B --> A: RequestCreated
deactivate B

A -> User: Done
deactivate A

@enduml

Its PlantUML output is:

PlantUML输出为:

Image 17

NConcern和CNeptune (NConcern and CNeptune)

NConcern and CNeptune are the AOP libraries that have been used for intercepting method calls of external applications in the SequenceDiagramDebugger sample. These captured method calls are visualized in the SequenceDiagramControl. The libraries are robust and well-designed: I was able to integrate them with minimum effort.

NConcernCNeptune是AOP库,已用于拦截SequenceDiagramDebugger示例中的外部应用程序的方法调用。 这些捕获的方法调用在SequenceDiagramContro中可视化。 这些库功能强大且设计合理:我能够以最小的努力将它们集成在一起。

NConcern provides the functionality and API for AOP (such as the advisors).

NConcern提供了AOP的功能和API(例如顾问程序)。

CNeptune is the mono.cecil based utility for rewriting .NET assemblies to make them injectable.

CNeptune是基于mono.cecil的实用程序,用于重写.NET程序集以使其可注入。

翻译自: https://www.codeproject.com/Articles/5259009/A-Dynamic-Sequence-Diagram-Visualization-Control

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FluentUI WPF是一个用于Windows Presentation Foundation(WPF)的开源UI库,它提供了一套高质量的UI组件和样式,用于构建具有专业外观和用户体验的应用程序。Fluent UI的名称来源于Microsoft Fluent Design System,这是微软公司推出的新一代设计语言,旨在提供一致、现代和直观的用户体验。 Fluent UI WPF提供了以下主要功能和特点: 1. 丰富的UI组件:Fluent UI WPF提供了各种常用的UI组件,如按钮、文本框、标签、列表、网格、布局容器等,以及自定义控件和工具提示等。 2. 美观的视觉效果:Fluent UI WPF具有高度定制的样式和外观,提供了多种主题和视觉效果,可以满足不同风格和场景的需求。 3. 可扩展性:Fluent UI WPF提供了丰富的自定义选项,可以根据具体需求定制组件的外观和行为,以满足个性化的需求。 4. 良好的性能:Fluent UI WPF在设计时注重性能优化,能够高效地渲染和响应用户操作,同时支持高性能的数据绑定和布局管理。 5. 跨平台支持:Fluent UI WPF不仅适用于Windows平台,还支持其他平台(如MacOS和Linux)上的WPF应用程序开发。 要使用Fluent UI WPF,您需要了解WPF的基础知识和设计原则,并具备一定的C#编程经验。您可以使用NuGet包管理器将Fluent UI WPF组件集成到您的项目中,并按照文档和示例进行配置和使用。Fluent UI WPF的文档和示例资源可以在开源代码库中找到。 需要注意的是,Fluent UI WPF是一个开源库,但并非所有功能都完全免费。某些高级功能可能需要购买商业许可才能使用。因此,在决定使用Fluent UI WPF之前,请务必仔细阅读相关文档和许可协议。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值