UML is undeniable a great tool to sketch up the architecture of a piece of software.
Many people, including me (a few months ago), hate the UML notation and may think that they won't need it in their daily lives. But it has been invented for a good reason: For communication inside teams.
This blog post is about my latest learnings on sketching up UML diagrams with the help of PlantUML.
After reading this: you will have built your first uml diagram by just using text.
Why should you care?
Code design is a part of our daily work. It might become less and less, going down the seniority ladder, but still. Even small code changes involve decisions about this topic.
Even if you are at the starting point of your carrer and won't have the reponsibility to design a new module, you will still want to understand existing modules. That's where UML diagrams enter the stage.
UML is a great tool to explain a programs design. It also serves as asset for discussions to find the best design.
That being said, here's what I've learned.
Drawing sucks! Use PlantUML
I have become a software developer, because I don't like drawing. I want to convey information as fast as possible. (Preferably without touching the mouse).
PlantUML is a open source software that takes text input (PlantUML syntax) and transforms it to beautiful UML diagrams.
It comes with all the features needed (and even more). Besides the classical class diagram, there are also sequence diagrams and many more.
Sounds cool? Let's get your first diagram drawn together!
Practical: Drawing your first class diagram
Let's start with a basic all known shop system. Our client says:
We want a shop system that has Users. A user can buy multiple items within an order. Every item has a price and. Every order has a total value. The order needs a billing address and a shipping address.
Before we get our hands dirty we should try to identify what we need for this draft. I like to mark the nouns in this sentence.
We want a shop system that has Users. A user can buy multiple items within an order. Every item has a price and. Every order has a total value. The order needs a billing address and a shipping address.
Let's write that diagram!
FOLLOW ALLONG: https://www.plantuml.com/plantuml/uml/
You need to start each diagram with @startuml and @enduml
@startuml
// your diagram
@enduml
Define the classes.
@startuml
class User {}
class Item {}
class Order {}
@enduml
This will leave us with following result
Adding properties
@startuml
class User {
+ firstName: string
+ lastName: string
+ id: string
- privateField: any
+ getFullName(): string
}
class Item {
+ name: string
+ cost: number
}
class Order {
+ items: Item[];
+ calculateTotal()
}
@enduml
Yeeting our code into the PlantUML engine, we are blessed with following diagram.
Defining relations between them is equally easy
Type of Connection | What is this for | Syntax |
Association | "There is a connection between both" | -- |
Composition | "Class B is part of this class" | --* |
Aggregation | "Class B is contained in this class" (It's like composition, but not exclusively used by this class) | --o |
Let's get that into our diagram.
@plantuml
class User {
+ firstName: string
+ lastName: string
+ id: string
- privateField: any
+ getFullName(): string
}
class Item {
+ name: string
+ cost: number
}
class Order {
+ items: Item[];
+ calculateTotal()
}
Order "1" --* "1..n" Item : "Has many"
User --o Order : "Contained in"
@enduml
This will leave us with following diagram.
This makes me happy, because with just a few lines of code we can get a fully featured UML diagram to discuss our code design with our colleagues.
Inheritance is easy
@startuml
class Employee {
}
class PayrateEmployee extends Employee {
+ payRate: number
}
interface PaymentProvider {
+ pay(amount)
}
class StubPaymentProvider implements PaymentProvider {
+ pay(amount)
}
@enduml
Custom arrow length
In the previous chapter I've talked about the different kind of associations. You can define the distance between two objects by using multiple -
or .
.
@startuml
class Employee {
}
class PayrateEmployee extends Employee {
+ payRate: number
}
interface PaymentProvider {
+ pay(amount)
}
class StubPaymentProvider {
+ pay(amount)
}
StubPaymentProvider ........|> PaymentProvider
@enduml
Oh and dots will give you a dashed line. While dashes will give you a full line.
Advanced: Using components for layered architecture
@startuml
component CoreLayer {
class User {
}
}
component UILayer {
class UserScreen {
}
UserScreen --* User
}
UILayer --|> CoreLayer
@enduml
There is a VSCode plugin to draw them locally
Don't waste your time with the web ui that refreshes every 5 seconds. Install the VSCode plugin: PlantUML
Want to know more?
Check out the very well built documentation page from PlantUML: https://plantuml.com/
Subscribe to the newsletter
I really enjoy writing this posts, so if you do so, share love by subscribing to the newsletter.