Introduction

I think everyone has heard the saying "Measure twice, cut once". It's true advice in programming. It's always better to think about the implementation before you spend any time carrying it out. During implementation, you often need to create classes and think up how they will interact. A visual representation of it all can often help you come up with most correct solution. This is where UML comes to our aid. UML: from theory to practice - 1

What is UML?

If you look at relevant images in search engines, you'll see that UML has something to do with diagrams, arrows and squares. You need to know that UML stands for Unified Modeling Language. Unified is the important word here. This means that our images will be understood not only by us, but also by anyone else who knows UML. It is the lingua franca for drawing diagrams.

According to Wikipedia,

"UML is a general-purpose, developmental, modeling language in the field of software engineering that is intended to provide a standard way to visualize the design of a system."
The most interesting thing, which not everyone would guess, is that UML has specifications. And there's even a UML 2 specification. More information on the specification is available on the Object Management Group website. In fact, this group develops the UML specifications. It is also interesting that UML is not limited to describing the structure of classes. There are many types of UML diagrams. Wikipedia has a brief description of various types of UML diagrams: UML diagrams. Returning to UML class diagrams, it's worth mentioning the book Head First Design Patterns", uses UML diagrams to illustrate design patterns. The bottom line is that UML really is used. And it turns out that knowing it and understanding how to use are quite useful.

Application

Let's figure out we can work with UML in an IDE. We'll use IntelliJ IDEA as our IDE. If you're using IntelliJ IDEA Ultimate, then we'll have the "UML Support" plugin installed "out of the box". It lets you automatically generate beautiful class diagrams. For example, use Ctrl+N or the "Navigate" -> "Class" menu item to go to the ArrayList class. Now in the context menu of the class name, select "Diagram" -> "Show diagram popup". As a result, we get a beautiful diagram. UML: from theory to practice - 2 But what if you want to draw the diagram yourself? And what if you don't have the Ultimate version? Using IntelliJ IDEA Community Edition, we don't have any other choice. So we need to understand how a UML diagram is organized. First, we need to install Graphviz. It's a set of graph visualization tools. The plugin we'll use depends on it. After installation, you need to add the bin directory from the Graphviz installation directory to the PATH environment variable. After that, in IntelliJ IDEA, select File -> Settings in the menu. In the "Settings" window, select the "Plugins" category, click the "Browse repositories" button, and install the PlantUML integration plugin. What's so good about PlantUML? It describes UML using a graph description language called "dot", which makes it more universal, since the dot language is used by more than just PlantUML. What's more, everything we do below can be done not only in an IDE, but also online at planttext.com. After installing the PlantUML plugin, we'll be able to create UML diagrams using "File" -> "New". Let's create a "UML class" diagram. This will automatically generate a template with an example. We'll delete its contents and add our own. To understand how to represent this in text, take a look at the PlantUML manual: plantuml class-diagram. UML: from theory to practice - 3Relying on these materials, let’s get started creating our UML diagram. Add the following content, which describes two classes:
@startuml
class ArrayList {
}
class LinkedList {
}
@enduml
To see the result in IDEA, select "View" -> "Tool Windows" -> "PlantUML". We just get two squares that represent classes. We know that both of these classes implement the List interface. This class relationship is called realization. This relationship is represented using an arrow with a dotted line. Let's draw it:
interface List
List <|.. ArrayList
List <|.. LinkedList
List is one of the Collection class’s children. That is, it inherits Collection. This relationship is called generalization. It looks like an arrow with an ordinary continuous line. Let's draw it:
interface Collection
Collection <|-- List
For the next type of relationship, add to the ArrayList class description an entry about a package private array of elements:
~Object[] elementData
Now we want to show that ArrayList contains some objects. In this case, there will be an aggregation relationship. ArrayList is an aggregate, since it contains other objects. We say aggregation because the list’s objects can exist without the list: they are not integral parts of the list. Their lifetime is not tied to the lifetime of the list. The word "aggregate" comes to us from Latin and translates as "assembled", that is, something made up of something. For example, in life, we have a pump assembly (aggregate), which consists of a pump and a motor. The assembly itself can be disassembled, and we can leave some of its components alone. For example, to sell or to put into another assembly. It's the same way in a list. This is expressed with an empty rhombus at the aggregate and a continuous line. We'll represent this as follows:
class Object{
}
ArrayList o- Object
Now we want to show that unlike ArrayList, the LinkedList class contains Nodes — containers that reference the stored data. In this case, Nodes are part of LinkedList and do not have an independent existence. A Node is not the content itself. It only contains a reference to the content. For example, when we add a string to a LinkedList, we are adding a new Node that contains a reference to the string, as well as a link to the previous and next Node. This relationship is called composition. It is depicted by drawing a continous line with a filled rhombus on the composite (something made of constituent parts). Now we'll represent the relationship as text:
class Node{
}
LinkedList *-- Node
And now you need to learn how to depict another important type of relationship: dependency. It is used when one class uses another, but the class does not contain nor inherit the used class. For example, LinkedList and ArrayList know how to create a ListIterator. We represent this as arrows with a dotted line:
class ListIterator
ListIterator <... ArrayList : create
ListIterator <... LinkedList : create
After doing all this, we get: UML: from theory to practice - 4You can add as much detail as necessary. Of course, there's nothing supernatural about drawing such a diagram. When working on your own tasks, you can quickly draw it out by hand. This will help you develop the ability to think through an application's architecture and identify shortcomings in the class structure early on, not after you've already spent the day implementing the wrong model. That seems like a good reason to try it, doesn't it? :)

Automation

There are various ways to automatically generate PlantUML diagrams. For example, IDEA has the SketchIT plugin, but it doesn't draw diagrams entirely correctly. Let's say the implementation of interfaces is drawn incorrectly (it is displayed as inheritance). The Internet has examples of how to integrate this into your project's build process. For example, you can find how to use uml-java-docklet with Maven. To demonstrate, we'll use Maven Archetype to quickly create a Maven project. Run
mvn archetype:generate
In response to Choose a number or apply filter, leave the default — just press Enter. It will always be "maven-archetype-quickstart". Select the latest version. Next, we'll answer some questions and finish creating the project: UML: from theory to practice - 5Maven isn't the subject of this article, so you can find answers to your questions about Maven in the Maven Users Centre. In the generated project, open the project description file, pom.xml, for editing. We'll copy the contents from the uml-java-docklet installing description to this file. The artifact used in the description can't be found in the Maven Central repository. But the following worked for me: https://mvnrepository.com/artifact/com.chfourie/uml-java-doclet/1.0.0. In other words, in the description you simply need to replace the groupId from "info.leadinglight" to "com.chfourie" and set the version to "1.0.0". After that, we can excute the following commands in the directory with the pom.xml file:
mvn clean install
and
mvn javadoc: javadoc
If we now open the generated documentation (explorer target\site\apidocs\index.html), we will see the UML diagrams. By the way, the implementation relationship is now displayed correctly :)

Conclusion

As you can see, UML lets you visualize the structure of your application. But UML can do much more. You can use UML to describe various processes within your company or to describe the business process that encompasses a function you're writing works. You'll need to decide for yourself how useful UML is for you personally, but no matter what you decide, it will be helpful to find the time to learn more about it.