Transcription
[Music]
Hello everyone!
I’m Mikhail Kazakov, a product manager at Sberbank. Today, I have my old friend Nikita with me. Nikita is a systems analyst and runs cool seminars, and he is also a great systems analyst.
Nikita, hello!
Hello everyone! I’m glad to see you all at the Flow conference.
Today, our topic is PlantUML. Nikita, could you please explain what PlantUML is, how to work with it, and what capabilities this tool offers?
Today, we will discuss this tool in detail, looking at what it is, the paradigm it operates in, its advantages, and its main drawbacks. If you discover any additional issues, please let me know; it will be interesting.
Most importantly, since this is a master class, we will practice together. We will prepare a simple sequence diagram, modify it, and review some life hacks through live examples that you can adopt in your practice. At the end, we will also discuss how the entire team can work collaboratively on a single file.
I want to remind you that we will have a Q&A session at the end of the presentation. Don’t forget to evaluate our talk. The Q&A will start immediately after the main part of the presentation, and you will be automatically redirected there.
Let me tell you a bit more about myself. Besides what Misha mentioned, I lead a team in devices, run a channel, and teach an author course where I prepare beginners who want to enter the profession. I also help practicing specialists and occasionally teach at an online school. Sometimes, I win hackathons and really enjoy conferences, not just as a speaker. I started my journey as a speaker by attending such conferences as a listener, and I always found it very engaging. So, kudos to you for participating in such activities!
Now, let’s talk about our beloved PlantUML. Why PlantUML, and why do we focus on UML as a notation? First, let’s see what one of the co-authors of this notation thinks about it. As we can see, he has a rather low opinion, although it’s just a joke referencing British politicians. He suggests that UML might be the worst modeling language, but only if we exclude all the others.
I conducted research among analysts, trying to include people outside my company to make it more representative regarding how popular this tool is, how often it is used, and for which diagrams. I found that most users primarily utilize it for sequence diagrams. That’s why today we will focus on the applicability of PlantUML for sequence diagrams.
So, what is PlantUML? It’s a diagramming tool that transforms pseudo-code into images. We will break it down today.
What’s great about it is that it’s available both online and locally. It generates images in various formats, the most popular being LaTeX, PNG, and SVG, and it integrates into many other systems. Here you see a lovely link.
Throughout the presentation, there will be many links; we leave them all in the slides so that after the talk, you can explore a wealth of useful materials. One of the most popular systems for integration is, of course, Confluence, and that’s how we use it.
PlantUML supports various diagrams, but we are primarily interested in sequence diagrams. I’ve also seen cases where it’s applicable for use case diagrams, class diagrams, and activity diagrams. It has grown beyond just UML diagrams. Interestingly, it can also be used to draw various YAML files. Essentially, it’s not just about building; it’s a graphical representation of what a YAML file looks like.
It’s very useful for other types as well, which you can explore in your free time.
What are the advantages of PlantUML? It’s an intuitive language that is easy to learn, especially for sequence diagrams. It’s also excellent for visual representation, allowing us to flexibly manage how and what we display. This is very convenient for large and complex diagrams because diagrams are created by people for people. You need to ensure that another person understands you, not machines.
This is not some BPMN engine; it’s a pseudo-code that turns into an image for others to work with comfortably. We can set a unified style in separate files and create libraries to avoid rewriting everything each time.
We will go through examples, and there’s convenient auto-numbering of steps and fixed distances, so you won’t have to worry about renaming everything if you need to insert a call after the 15th step.
Exporting to images supports hyperlinks, meaning if you download it and there were hyperlinks, they remain active even in the downloaded format.
There are also some finer settings in PlantUML that we will discuss today, including various functions. Naturally, PlantUML files support version control for tracking changes.
What I particularly like is that it allows us to collaborate on a shared diagram without conflicts. Each person can work independently on their diagram. We will review an example of this at the end.
What are the identified drawbacks of PlantUML? It can be quite challenging to influence the arrangement of elements in some diagrams. However, for those who really want to tackle this, check out what Dot is. PlantUML is built on top of it. It’s a low-level display language where you can draw anything with dots if you wish.
PlantUML is a higher-level language that fixes some placements and distances to make it easier for you, but it takes away some of your freedom. Not all diagrams are suitable for transfer, so please remember that. If you see a tool, it doesn’t mean it’s a silver bullet; you need to weigh the pros and cons and understand where it’s appropriate to use and where it’s not.
Two things that might be unclear now but we will understand through examples regarding the drawbacks are that aliases when aggregating files must match. I will show you where, and the Return function is a response message that can be unpredictable, so I recommend not using it.
As for how to work with it locally and online, I’m leaving all the links here. Personally, I work with Visual Studio Code, and everything you need for packages is on the slide. I know there are plugins for Eclipse as well, so you can check those out.
PlantUML is supported in many places, or you can also integrate it into a text editor, but I don’t recommend using any text editors, even with plugins, because some later features of the tool are not supported there.
For work, you need an IDE. Downloading one is free, and they highlight syntax beautifully, allowing you to work with it effectively.
Here are some online tools as well. You can find more, but today we will need the first one, PlantText. It will appear in the chat shortly. We will use it for exercises.
This online tool means you can practice writing some pseudo-code, hit Alt + Enter or Refresh, and it will display how it might look as an image. If you follow this link, you will find pre-filled code. If you haven’t used this link before, it’s StartUML.
Next, you might have a file name, which is set locally and only visible in the code; it doesn’t affect the image. The sequence code shows that from point A to point B, source 10 is less. We display that from Bob, an arrow pops out, a colon, and what message to draw on the arrow.
It takes the code and draws it for us, completing the code structure. It’s simple.
Now, let’s practice this skill together. I will give you a practical task using that PlantText link in the chat. I want to see a simple scenario for ordering a bouquet.
To avoid interrupting you with the names of all the calls and components, they will also appear in the chat shortly, and I will explain what should appear.
This image will be in front of you after you complete the task. You have three components: user, client, and server, and here are the calls between them: filling the cart, displaying the order, passing the data, processing it, updating the status, passing the status again, and displaying it.
Let’s limit ourselves to this process. I’ll set a timer for three minutes, and the time starts now.
Let’s see what you come up with. Maybe Mikhail will come to me with some interesting questions he has gathered. I’m waiting for your completion; write a plus as soon as you finish the task, and we will discuss it.
An interesting question came up: how do you encourage developers to read? I can share my experience. I always describe integrations and complex interactions as much as possible. We try to draw sequence diagrams where possible, and when needed, we draw status diagrams, but those are less frequent.
We always strive to cover all technical aspects, and as someone mentioned in the chat, any integration can turn into a nightmare without proper documentation.
There’s also a general answer that can apply not only to UML but to how to encourage developers to adopt certain techniques. The best answer is to lead by example. If not your own, then show a positive example. Demonstrate how much easier it is when you implement something and genuinely use it, and people will gradually follow suit.
Eventually, everyone will wake up to the fact that this has become a standard practice, and they can’t live without it. They will get used to it, and breaking that habit will be undesirable, so they will continue.
Don’t hesitate to take the initiative. If no one has used UML and it’s appropriate to use it, try promoting it yourself. Show it, organize demonstrations, workshops, and everything else.
For example, if your team is already using UML but hasn’t reached PlantUML or a similar method of conveying this practice, it’s worth using.
Nikita is curious about why the display of the order sent for processing comes before the order data is sent to the server.
You see how difficult it is when there are no numbered steps in the diagram; it’s immediately unclear which step is being referred to.
Let’s clarify again: which step comes before which? The display of the order sent for processing comes before the data sent to the server.
This can be done; it’s called an optimistic update. We show the user that everything is fine, relax, put down the phone, and focus on other things; we have everything under control. In reality, we don’t have everything under control yet, and we are running behind the scenes trying to keep up.
So, this is an acceptable practice, especially for our simple case, where we guarantee delivery to that server.
Here, errors are not considered alternatives; we will touch on that later when discussing how to work with alternatives in UML.
So, three minutes have passed. How are we doing with the pluses from the participants?
No one is writing. I think that’s good; let’s move on to see what you’ve accomplished. If this is your first time encountering PlantUML, your image will likely look like this.
The only difference might be the call for passing the order status back. You might have it as a solid arrow; see, the response message is represented by two dashes. I recommend using those instead of the Return function; trust me, you won’t encounter unnecessary problems.
Now that you have this in front of you, let’s return to reality. Imagine a client or manager comes to you and says, “Okay, this is all interesting, but we don’t have a user; we refer to our users as ‘dear clients’ and our server as ‘magnificent server.’ So, we urgently need to adjust our diagram.”
We should not only return the status but also the order cost, and we need to think about the future. An architect has suggested placing brokers and a database between the client and server.
As we’ve already discovered from the questions I received, it’s very difficult without numbering. We need to number the steps and ensure that all icons are clear.
In the end, we should have an image like this. I’m giving you very little time—just one minute. You probably won’t be able to implement these changes in a minute, but give it a try.
Let’s see if anyone can manage to do it in that time.
Mikhail, do you have any updates on the pluses?
I hope those pluses are for the previous task. They tricked me and completed the second task in ten seconds!
Nikita, here’s a question: various diagrams are often drawn in different teams, and we need to merge several diagrams into one. Can you share some convenient ways to do this?
Yes, this need arises, especially in large distributed teams or even in smaller teams that consist of atomized subgroups, where each works within its context, and someone needs to synchronize everything into a single picture.
This can be challenging, requiring a lot of manual work—going through each diagram, reviewing, and pasting separate pieces together on a whiteboard.
I’ve devised certain tricks to simplify this process, and we will review them at the end.
So, it’s been about a minute and a half. How are we doing with the pluses in the chat?
No pluses yet.
It seems this exercise is going as planned. Now, let’s move on to the magic session with full disclosure.
Let’s look at this wonderful pseudo-code and the tricks we used to achieve such an image in such a short time.
First, we have a fantastic auto-numbering feature that numbers everything for us. Even if we insert steps in the middle, it’s designed to handle that.
You can also flexibly manage the starting number, for example, starting from zero if you’re a seasoned programmer, or set steps of ten, and so on. You can embed any logic you want.
Next, we set the skin parameters, max equal to a certain value. It allows us to automatically position the text above the calls so that it doesn’t stretch the diagram unnecessarily.
We can also choose different icons using reserved words for our components and actors. For example, the database icon is drawn slightly differently, which is also convenient for perception.
We can assign explicit names to our components and aliases. You see, this dear user is represented by an alias.
In the code, we don’t write the full name of our component each time. If we want to rename it five times, we only need to change it in one place, and it will apply everywhere.
Using aliases is physically easier. I don’t recommend making them one letter; write something more meaningful, like User.
Another useful feature is that we can insert two components using the order parameter, like order 10 and order 20. This indicates where to place the current component in relation to others.
If we initially had three components placed as 1, 2, and 3, we can later add brokers and databases between them by simply assigning their order within the tens, like between 20 and 30.
The code is straightforward. Here, we declare a variable and assign it a value, like status and order cost.
You see, it’s like a cost, and then we pass this variable using a dollar sign without an exclamation mark above each call. The diagram automatically draws the value of this variable, status, and order cost.
This is very convenient when you have a piece that repeats, especially if you need to edit it.
Let’s move on to more life hacks with live examples. First, a bit about Visual Studio Code. I won’t spend much time on it; check it out separately for various functions that make it easy to work with.
Now, let’s look at another exemplary case. How can we achieve such a display?
First, as you’ll notice, we can draw response messages in either direction. The main message can also be directed any way we want.
For response messages, we can use two dashes. I don’t recommend using the Return function; it’s very risky.
We can set the title of the diagram either on the image using the title command or in the PlantUML file, as we saw near the system word StartUML.
We can also set a header with a title, and if we want, we can include various functions, like counting the current page from the last page.
All this is available in the guides, so we won’t dwell on it. Just know that there are various interesting functions and procedures.
As agreed, use aliases with an S and order with a step of 10. Here’s how it looks.
This is how it appears on the diagram, and this slide with skin parameters doesn’t appear anywhere; it’s just for the file.
The Return function worked correctly, but there are cases where it doesn’t work properly, so honestly, just use the double dash and the arrow in the other direction.
What else do we have? Auto-numbering, auto-numbering with equal spacing between components, and setting the size of these spacings.
It’s also convenient to set these parameters in an array so you don’t have to repeat them each time.
For sequences, we set a minimum distance of thirty, so they don’t crowd each other, even if the messages are short.
We can also center the messages above the arrows.
What else do we have? Line breaks can be done with a backslash, allowing us to break lines wherever we want.
Or, my favorite, we can set Max message size to, say, 300, and all messages will conveniently wrap.
Just in case, I mention that you can escape with another backslash if you need to.
Looking at steps 5 and 6, we see that step 5 was manually moved using a backslash, while step 6 was automatically wrapped thanks to our Max setting.
The color scheme can be useful for segmenting networks. For example, we can indicate that this is public, and that’s on our server, while this is a local contour without internet access.
It’s also useful to color different scenarios, like alternative flows.
Let’s see how this can look. Here’s a box labeled “net segment Public,” and we specify the color using a hash.
You can use hexadecimal formats and reserved HTML color names. Choose what works for you.
In the box, we simply list what we want to include. You can use boxes for any purpose, not just for network segments.
Next, we have comments. An apostrophe denotes a single-line comment, while a slash and apostrophe denote a multi-line comment.
Let’s look at these lovely groups. We can create a custom group, give it a name, and describe everything that happens within it.
We can also set alternatives using a reserved word, assigning a color. If your friend can’t see it, it’s a pale green, indicating a success branch, while pale pink indicates a failure branch.
When there are many calls and nested alternatives, this differentiation is very convenient. Just remember to define the rules of UML, indicating when a user falls into this branch.
In this case, the list of success criteria is clear, so PlantUML will draw it conveniently.
If you have equivalent alternatives, like “What day of the week is it?” you can simply alternate colors.
What else is useful? You can add notes to any piece of code and specify where it should be displayed, along with its color and font.
This is how it’s written if we want to indicate that we need to place a note to the right of the last call.
Let’s move on.
What else should you remember about the color scheme and working with PlantUML? Don’t forget about tabs; leave comments where needed, and group entities for easier reading later.
Trust me, this will be useful, especially for others who might work with this diagram.
Ensure there’s a consistent style, and you can set a prefix for auto-numbering. You don’t have to set one, but if you need it, you can start from zero.
We won’t cover all the nuances of skin parameters, but I’m leaving all this on the slides so you can try it out and see how these parameters affect your diagram.
When you have access to this presentation, all the code inside will be copyable, so you can experiment and see what results you get.
I’ve tried to list not all skin parameters, but those that might have some significance for your display. You can find much more information in the manuals.
As I mentioned about auto-numbering, we can start from number 45 and go to 5, setting a prefix like “message.”
We can also set a color, so experiment and imitate exactly as you need.
What else can be useful in PlantUML? You can create a legend, fully controlling its title, position, and sections, leading numbered and bulleted lists, and inserting hyperlinks.
Remember that hyperlinks remain active when exported to SVG.
Here’s how it might look. We create a legend with its color and size, and it can be placed at the bottom.
It’s also convenient in large distributed teams to document what version it is, what features it works with, your diagram above, who the author is, and so on.
All this can be easily included, and you can even embed hyperlinks.
What else can be useful? You can create a reference, especially if you have a history of authentication or authorization, and the user needs to be authorized by that moment.
You can create a box labeled “ref” to clarify and say, “Look at this other diagram where this process is described.”
This can be very convenient.
We can also separate by use cases or any other sections you find necessary, coloring them as needed.
You can follow pure UML and use these active lines to show that components are functioning at that moment.
Many people overlook this, but if it’s important for your team, consider using these active lines to maintain that bold line.
Next, we have numbered lists. Here’s how they appear.
It’s convenient for methods to show that we are passing specific key parameters, listing them, and building their hierarchy.
If we want to indicate that something should be displayed on the client, all examples of how to do this are on the slide.
It’s better to practice at home, looking for what suits you best in different display options.
I’ve also left comments for you to choose the most suitable one for yourself.
Now, let’s get into return functions. For those who thought this was just a display tool, it’s not that simple.
The creators introduced functions that resemble procedures and have a syntax for declaration. We define them in a box, with the name following the dollar sign.
You list all the arguments it takes as input, and you can also set a default value for an argument if you don’t specify it when calling the function.
Of course, you write what the function will return. Simple aggregation operations can be performed with the pre-defined string.
We can do something with these arguments, like multiplying or adding them, depending on what you pass as input.
We can call it directly on the sequence arrow, which is convenient, or assign it to a variable to use that variable on the sequence arrow without cluttering it.
We can also create nested calls within another function or procedure.
As we saw, variables are defined with an exclamation mark and a dollar sign, and if we want to specify that a local variable lives in a certain piece of code, we use Local if that becomes necessary.
You can look into this in more detail, but it’s a rare case.
Here’s a brief look at how this beauty looks. For example, we have a function that takes an argument.
What does it do? It doubles the input. We declare some arguments, like two and five, and call it here.
The function takes our argument, and it doubles it, turning two into four.
You can also play with various conditions and more.
If you think functions are complex, you can go further because there are procedures.
These can even generate a piece of code for you if you don’t have it. You call a procedure that’s defined somewhere, and it generates several steps based on the arguments you pass.
The syntax for defining it is similar. It’s important to call it not just by name but with the command to invoke the procedure.
You might wonder when this could be useful.
Here’s a situation: often, a certain call with specific data is repeated, and in components, they simply proxy, passing data back and forth without any logic happening.
For such cases, you can use custom procedures for proxying.
Here’s how it might look. I’m leaving you examples, including how to insert beautiful icons in boxes.
You can check these out separately.
Let’s say we have a magical procedure called “proxy,” which takes a message we need to proxy and the aliases in the order they need to be displayed between components.
We call it, saying, “Please invoke the procedure named proxy.”
This will generate a single line that gets drawn very conveniently.
The same goes for the reverse direction.
We assign a variable and say it’s a file plus link, and we call another procedure, proxy response, drawing responses with dashed lines.
This is a very convenient feature, and I recommend using it.
I’ll show you a file with procedures where this beauty is implemented. Don’t try to delve into it; it’s already done.
We had a need for such procedures, and I actively use them. I recommend you not waste your time inventing such procedures; you can copy them into your library and call them when needed.
Lastly, I’ll briefly mention that you can draw mockups in PlantUML.
There are situations where clients want to see updates under each button, and I know people have coordinated various mockups with snapshots, which can be inconvenient.
Sometimes, it’s easier to do it with pseudo-code because it’s much simpler to track version changes.
These mockups are written in PlantUML, and you can embed them in sequence and activity diagrams.
We won’t cover everything now, but I’ve provided various options for you to copy and adopt.
Now, let’s talk about aggregation—the team collaboration I promised you at the beginning.
Why might we need this? For distributed teams, for example, to send notifications, we need to generate them on our end and pass them to another team that handles all notifications in a super application where we are just one module.
Then that team will pass it to a third team that manages all notifications from your organization, and so on, until it reaches the client.
You can feel that there are many different teams with their cycles, and tracking this chain from start to finish can be very challenging.
What can we do? We connect Git and work in a shared repository. Each person works on their part of the diagram, packaging and wrapping notifications.
This way, we upload it to Git. By the way, here’s a real level; you can import it and try it out later with styles.
Using Rails, we can import a library from the code and keep a file with styles, establishing a unified corporate style once.
Everyone imports it, so there’s no need to remember colors and styles.
Each team works on its part, and you aggregate it. You have an intuitive scenario that doesn’t need to be updated manually.
As soon as you look at the image, it automatically pulls from all these includes and assembles the overall aggregate.
Even the configuration page won’t change its version.
It’s convenient that independent changes in parts don’t require updating the aggregate.
What you need to remember, as I mentioned at the beginning, are the drawbacks of PlantUML.
Remember that the naming of aliases for participants must match across all files. If you have a user as US, then other teams must also have it as US so that PlantUML understands that the arrows originate from it.
I’ll also touch on how to include files in various ways—through direct import, function insertion, or via a URL.
I won’t dwell on this in detail; I’ll leave it on the slide for you to use.
There’s also a procedure called cloat JSON for those working with JSON files who want to visualize their diagrams.
It’s not so obvious; you need to do it through a separate procedure, and I’ll leave an example of its use on the slide for you to study.
In the end, you can achieve something beautiful like this.
If this is relevant to someone, I’ve gathered sources for you to draw information from, real examples, and other things I haven’t touched on yet.
You might find it useful as an encyclopedia.
First, there’s Real World PlantUML, where people share real examples from practice. I haven’t encountered anything as intricate as what I prepared, but it can be useful to copy and adapt.
If you want to delve deeper into PlantUML, the official guide is very helpful.
I recommend the PDF version because it’s easier to search for the functions you need.
The customization options in PlantUML are incredible, and you’ll likely find ways to do things you hadn’t thought of.
This is the primary source to work with if you want to find something more exotic.
There are also other interesting tools; be sure to play around with them.
These include text diagram tools that show how various diagrams can be drawn in different languages.
If you want to explore beyond just PlantUML, let me know if you find any interesting applications.
Now, before we move on to discussion and questions, let’s recall the diagram we conveniently used with procedures.
Imagine this is just part of our work. In reality, our entire process involves several teams.
I won’t ask you to scrutinize it; it’s intentionally small.
I’ll pose a question for discussion: how many lines of code do we need to assemble and display such a large diagram?
Think about it during the discussion.
I want to thank you for your attention. This was not the simplest presentation; there was a lot of information.
Great job if you managed to keep up with this focus, especially participating in the interactive part.
Our brains remember information best when we process it through our mistakes.
I’m ready to share my contact information and answer your questions while we’re still live.
Thank you, Nikita!
There was a very interesting question about examples of use and general patterns across teams for drawing a unified cross-team diagram.
Can you share examples of how your team interacts?
Yes, it’s often convenient when several independent teams with separate managers need to support a cross-functionality.
They all sign off on it, and it needs to be tracked.
If we send a JSON at the beginning, it should reach the end as a JSON.
This helps to look at the entire process from start to finish.
We can track it using such imports into a common aggregate diagram, allowing us to see all steps and where things happen.
It’s also useful for tracking memory leaks or battery drain, identifying which steps are causing issues.
If teams are doing the same thing without knowing it, seeing it on a common picture helps us understand where we can save battery for our users through technical process optimization.
Another way to use these imports is to create a unified style file.
If each analyst colors their diagrams differently, it can be challenging to navigate.
Establish a unified style file with all your corporate colors and spacing, and simply import it.
If you take the initiative to prepare such a file, everyone can easily import it without any hassle.
Thank you very much!
I think we can wrap up our discussion here.
For those interested, we invite you to the discussion room. A link will appear shortly in our broadcast automatically.
Thank you all!
Goodbye!
Please share your feedback; I’m always interested in what can be improved in the presentation.
You can do this later or while joining the discussion.