[38;5;244m┌─[0m [38;5;40mroot@joaocosta:~#[0m [38;5;245mcat posts/5.md[0m [38;5;244m────────────────────────────────────────────[0m

[38;5;40m#[0m [1mDraw UML diagrams with PlantUML[0m
[38;5;245mpublished 2020-06-20 · 7 min read · https://joaocosta.dev/blog/5[0m

The second semester is starting and I now have a Data-Bases class (will refer to
it as BDAD from here on). In this class we're making heavy use of [38;5;40mUML[0m
[38;5;244m(https://www.uml-diagrams.org/)[0m, more specifically [38;5;40mUML class diagrams[0m
[38;5;244m(https://www.uml-diagrams.org/class-diagrams-overview.html)[0m. I am using PlantUML
for that, so I'll talk about it and why I chose it.

[38;5;38m##[0m [1mHow I've used UML before[0m

Up until this semester, I haven't used UML that much. As a matter of fact, I
only used UML for a project on the last semester and it was a really limited UML
application. Even with this new university class, I've been drawing my UML with
pencil and paper (like most people I see). Needless to say that this isn't
exactly efficient, specially when I need to correct mistakes. Before talking
about [38;5;40m[1mPlantUML[0m[0m [38;5;244m(https://plantuml.com/)[0m, I believe I should talk about the other
alternatives I've tried that (I liked) and why I didn't stick to them.

[38;5;38m##[0m [1m[38;5;40mdraw.io[0m [38;5;244m(https://www.draw.io/)[0m[0m

[1mDraw.io[0m is great for those moments when you're not in your usual working
environment and need a quick diagram drawing tool, or when you only need to draw
diagrams very sporadically. It is most often used as a web-application, but it
also has a desktop version that I never tried. From what a friend told me, it is
the same as the web app, but it can be used offline.

The things I loved the most about [1mdraw.io[0m are:

[38;5;40m→[0m It is open [38;5;40msource[0m [38;5;244m(https://github.com/jgraph/drawio)[0m;
[38;5;40m→[0m It is an instance of what I like calling [3m"a good web app"[0m. It works on the [38;5;40mTor
  browser[0m [38;5;244m(https://www.torproject.org/)[0m, even with all cookies blocked and
  non-free [1mjavascript[0m disabled;
[38;5;40m→[0m It is extremely user-friendly and [3mstraight to the point[0m.

My problem with it was that it didn't support [3massociation classes[0m: it neither
has the type of arrows needed, nor allows to connect an arrow to another.

[38;5;38m##[0m [1m[38;5;40mModelio[0m [38;5;244m(https://www.modelio.org/)[0m[0m

I'm going to be honest, I didn't have high expectations for this one since it
was recommended by my teachers. Still, it is open-source, extensible, and seems
to have a decent community that keeps the project alive.

It had a lot of dependencies that I didn't have installed and was extremely slow
when creating a project on my machine, so I gave up on it. I thought about not
listing it here since I almost didn't try it. Still, I believe you should give
it a try if you're looking for a GUI application, because you might have more
luck with it than I did.

[38;5;38m##[0m [1m[38;5;40mDia[0m [38;5;244m(https://wiki.gnome.org/Apps/Dia)[0m[0m

I thought I was going to hate [1mdia[0m (because Gnome), but it surprised me. I didn't
need to install any dependencies and the GUI was simple and fast. Even without
having ever looked/read about at it before, all options I wanted were in the
places I expected them to be.

It is an [38;5;40mopen-source[0m [38;5;244m(https://gitlab.gnome.org/GNOME/dia)[0m project, but looks a
bit abandoned. The few recent commits are mostly fixes/additions to translation
efforts. Either way, it looks fairly complete.

Remember the [3massociation classes[0m problem I had with [1mdraw.io[0m? I had the same
problem with [1mdia[0m. I found [38;5;40mthis[0m
[38;5;244m(https://stackoverflow.com/questions/6139951/how-to-draw-an-association-class-in-dia/14344657#14344657)[0m
answer on a [3mstackoverflow[0m post dating back to the beginning of 2013. It says
that the [3mdevelopment branch[0m of [1mdia[0m added the ability to connect UML arrows to
one another. I cloned and built the [3mdevelopment branch[0m and I can confirm that it
does indeed add that ability. The question now is why isn't this function in the
[3mrelease/master[0m branch after (at least) 7 years. Anyway, [1mdia[0m doesn't have the UML
arrow I need for this either way, so it didn't solve the problem completely. The
auto-routing is also somewhat bad, which meant the search would go continue.

[38;5;38m##[0m [1m[38;5;40mUmbrello[0m [38;5;244m(https://umbrello.kde.org/)[0m[0m

This program is amazing and I recommend it to anyone that feels comfortable
using GUI's and doesn't care about program sizes. It is open-source, supports
code translation from and to UML for many programming languages, and can easily
and seamlessly handle UML [3massociation classes[0m and their arrows.

Although [1mumbrello[0m has all this great things, it is huge. Definitely too huge for
me and for what I think it should be. In my machines, I need to install [1m32[0m
dependencies to use [1mumbrello[0m, so I stuck with [1mdia[0m for a while.

[38;5;38m##[0m [1mGoodbye GUI's[0m

So after all that search, I kept using [1mdia[0m on the [3mdevelopment branch[0m with some
weird arrows (that weren't even on the UML set) to connect the [3massociation
classes[0m. It was still better than drawing everything by hand. When I'm drawing a
UML [3mclass diagram[0m from a textual description (BDAD exercises), I start by
writing a [3mrelational model[0m as I'm reading the text. This got me thinking. I had
read about drawing UML diagrams in LaTeX before. Maybe I would be able to
combine the steps of writing the [3mrelational model[0m and drawing the [3mclass diagram[0m
into one (and show off to my friends). Turns out I can with [1mPlantUML[0m.

[38;5;135m###[0m [1m[38;5;40mPlantUML[0m [38;5;244m(https://plantuml.com/)[0m[0m

[1mPlantUML[0m is open-source and strives to be as compact as possible. This means
that you only have the base set of features by default (which means you're just
missing some output formats). If you want/need some other features, you can
install the dependencies. I love this design choice.

The greatest thing about [1mPlantUML[0m is that you describe the UML diagrams using a
special textual syntax (similar to a scripting language). I know this may sound
really weird (it sounded weird to me), but it's great. You can draw UML diagrams
faster than with GUI applications and still watch live previews of your work:

[38;5;40m→[0m a [38;5;40mVSCode extension[0m
  [38;5;244m(https://marketplace.visualstudio.com/items?itemName=jebbs.plantuml)[0m;
[38;5;40m→[0m many vim plugins like: [38;5;40mplantuml previewer vim[0m
  [38;5;244m(https://github.com/weirongxu/plantuml-previewer.vim)[0m, [38;5;40mplantuml-syntax[0m
  [38;5;244m(https://github.com/aklt/plantuml-syntax)[0m and [38;5;40mvim-slumlord[0m
  [38;5;244m(https://github.com/scrooloose/vim-slumlord)[0m;
[38;5;40m→[0m output the UML to PDF and use a PDF viewer that can update the shown contents
  automatically, like [38;5;40mZathura[0m
  [38;5;244m(https://joaocosta.dev/blog/%3Chttps://en.wikipedia.org/wiki/Zathura_(document_viewer)[0m>):
  [38;5;38mplantuml -tpdf <file_name>[0m;
[38;5;40m→[0m use the included [1mPlantUML[0m GUI: [38;5;38mplantuml -gui[0m;
[38;5;40m→[0m just output to default png format and use an image viewer;
[38;5;40m→[0m integrates with [38;5;40mLaTeX[0m [38;5;244m(https://plantuml.com/latex)[0m;
[38;5;40m→[0m or try one of the [38;5;40mtools[0m [38;5;244m(https://plantuml.com/running)[0m listed on their
  website.

There are also [38;5;40mtools[0m [38;5;244m(https://plantuml.com/running)[0m for generation code from and
to [1mPlantUML[0m like [38;5;40mhpp2plantuml[0m [38;5;244m(https://github.com/thibaultmarin/hpp2plantuml)[0m.

[38;5;135m###[0m [1mPlantUML's examples[0m

[38;5;244m┄────────────────────────────────────────────────────────────────────────── js [0m
[38;5;245m│[0m @startuml
[38;5;245m│[0m title Basic syntax example
[38;5;245m│[0m 
[38;5;245m│[0m 'this is a comment'
[38;5;245m│[0m class Name {
[38;5;245m│[0m   name
[38;5;245m│[0m }
[38;5;245m│[0m 
[38;5;245m│[0m class ID {
[38;5;245m│[0m   id
[38;5;245m│[0m }
[38;5;245m│[0m 
[38;5;245m│[0m /'
[38;5;245m│[0m this is a class with some parameters
[38;5;245m│[0m and 1 method
[38;5;245m│[0m '/
[38;5;245m│[0m class Person {
[38;5;245m│[0m   name
[38;5;245m│[0m   id
[38;5;245m│[0m   getID()
[38;5;245m│[0m }
[38;5;245m│[0m 
[38;5;245m│[0m 'these are generalization arrows'
[38;5;245m│[0m Person <|-- Name
[38;5;245m│[0m 'this arrow has the same meaning as the one above'
[38;5;245m│[0m Person ^-- ID
[38;5;245m│[0m 
[38;5;245m│[0m 'this is an association arrow'
[38;5;245m│[0m Person - Car
[38;5;245m│[0m 'this is an association class arrow'
[38;5;245m│[0m (Person, Car) .. IsOwner
[38;5;245m│[0m 
[38;5;245m│[0m @enduml
[38;5;244m┄──────────────────────────────────────────────────────────────────────────────[0m

The 'code' above is a really simple example of PlantUML's syntax that produces
the following image when the command [38;5;38mplantuml <file_name>[0m is run:

[38;5;40m→[0m [38;5;245m[image][0m Basic UML example
[38;5;244mhttps://joaocosta.dev/_resources/b25a2e2d9fa7ae33c0efc1e58983e237.png[0m

The [38;5;40mcolors/themes[0m [38;5;244m(https://bschwarz.github.io/puml-themes/)[0m are all
customizable, you can define the directions of the arrows, and you can tell
[1mPlantUML[0m to group certain 'objects' together, so you can end up with something
that looks like this (I'm sorry for your eyes):

[38;5;40m→[0m [38;5;245m[image][0m Ugly colors example
[38;5;244mhttps://joaocosta.dev/_resources/7c51f73f1abd04ee2792786565caed4d.png[0m

This is the 'new code' to get the result above:

[38;5;244m┄────────────────────────────────────────────────────────────────────────── js [0m
[38;5;245m│[0m @startuml
[38;5;245m│[0m 
[38;5;245m│[0m skinparam backgroundcolor Black/Orange
[38;5;245m│[0m 
[38;5;245m│[0m skinparam class {
[38;5;245m│[0m   BackgroundColor PaleGreen
[38;5;245m│[0m   ArrowColor SeaGreen
[38;5;245m│[0m   BorderColor SpringGreen
[38;5;245m│[0m }
[38;5;245m│[0m 
[38;5;245m│[0m title Ugly colors example\nwith arrow directions
[38;5;245m│[0m 
[38;5;245m│[0m 'this is a comment'
[38;5;245m│[0m class Name {
[38;5;245m│[0m   name
[38;5;245m│[0m }
[38;5;245m│[0m 
[38;5;245m│[0m class ID {
[38;5;245m│[0m   id
[38;5;245m│[0m }
[38;5;245m│[0m 
[38;5;245m│[0m /'
[38;5;245m│[0m this is a class with some parameters
[38;5;245m│[0m and 1 method
[38;5;245m│[0m '/
[38;5;245m│[0m class Person {
[38;5;245m│[0m   name
[38;5;245m│[0m   id
[38;5;245m│[0m   getID()
[38;5;245m│[0m }
[38;5;245m│[0m 
[38;5;245m│[0m 'you can change the direction of arrows'
[38;5;245m│[0m Name -down-^ Person
[38;5;245m│[0m 'you can abreviate (d)own, (u)p, (l)eft and (r)ight'
[38;5;245m│[0m Person ^-u- ID
[38;5;245m│[0m 
[38;5;245m│[0m 'this is an association arrow'
[38;5;245m│[0m Person -l- Car
[38;5;245m│[0m 'this is an association class arrow'
[38;5;245m│[0m (Person, Car) .. IsOwner
[38;5;245m│[0m 
[38;5;245m│[0m @enduml
[38;5;244m┄──────────────────────────────────────────────────────────────────────────────[0m

I'm not going to talk about all the syntax in depth because I don't need to.
[1mPlantUML's[0m [38;5;40mlanguage specification[0m
[38;5;244m(https://plantuml.com/sitemap-language-specification)[0m is very well written,
explicit and filled with examples. The syntax is so simple and easy that you
should be able to start drawing mundane UML [3mclass diagrams[0m just by looking at
the examples above and checking the syntax for the different [38;5;40mUML arrows[0m
[38;5;244m(https://plantuml.com/class-diagram)[0m. It really is that easy.

[38;5;135m###[0m [1mThe bad[0m

If you're collaborating with other people, you'll probably not be able to get
them to use [1mPlantUML[0m, considering that most people prefer GUI's for everything.
This means that you'll likely only benefit from the time invested learning the
syntax when working in personal projects. Although the auto-routing is quite
good (most of the time), and you have options to group 'objects' and choose the
direction of the arrows, I still find that the diagrams don't always look
perfect. I believe this probably happens because I'm a new user, so I'm just
missing experience with the program to get everything looking the way I want.
Either way, this is the biggest barrier to entry on [1mPlantUML[0m. You have to rely
quite a lot on the auto-routing because you can't simply drag the connections
around. Sadly, it looks like [1mPlantUML[0m doesn't support (at the time of writing)
[38;5;40m_association qualifiers_[0m [38;5;244m(https://www.uml-diagrams.org/property.html#qualifier)[0m.
Good thing I haven't needed them (yet).

[38;5;38m##[0m [1mClosing remarks[0m

After a lot of reading, searching, and trying out different programs, I found
[1mPlantUML[0m and I'm in love with it. It reminds me a lot of when I first used
[1mmarkdown[0m. I was skeptical, but ended up liking it. If you need to draw UML
diagrams for a project and you can decide the tool used, I recommend [1mPlantUML[0m.
It is fun, simple to use, free, it feels familiar to programming, and it has
many tools, plugins and programs that integrate with it. It is just great. This
post wasn't very 'technical', because I didn't find the need for it. I just
wanted to share my opinions on [1mPlantUML[0m and maybe convince people to use it. I
wouldn't be able to do a better job at explaining how to use [1mPlantUML[0m than its
[38;5;40mdocumentation/language specification[0m
[38;5;244m(https://plantuml.com/sitemap-language-specification)[0m. On another note, I
started using a [3mMakefile[0m to deploy my website changes, instead of my [38;5;40mold deploy
script[0m [38;5;244m(https://www.joaocosta.dev/blog/how_create_page/#my-deploy-script)[0m. I'm
still pondering if I should edit that post, so it would also include the
[3mMakefile[0m, but for now I'll leave it here.

[38;5;244m┄────────────────────────────────────────────────────────────────────────── js [0m
[38;5;245m│[0m # your output directory (e.g.: public)
[38;5;245m│[0m OUTPUT_DIR = public
[38;5;245m│[0m # your website url (e.g.: www.joaocosta.dev)
[38;5;245m│[0m CNAME = www.joaocosta.dev
[38;5;245m│[0m 
[38;5;245m│[0m default: server
[38;5;245m│[0m 
[38;5;245m│[0m .PHONY: clean
[38;5;245m│[0m clean:
[38;5;245m│[0m 	@echo "cleaning"
[38;5;245m│[0m 	@# clean all files (except hidden files like '.git')
[38;5;245m│[0m 	rm -rf ${OUTPUT_DIR}/*
[38;5;245m│[0m 	mkdir -p ${OUTPUT_DIR}
[38;5;245m│[0m 	@# write the CNAME file
[38;5;245m│[0m 	printf "%s" ${CNAME} > ${OUTPUT_DIR}/CNAME
[38;5;245m│[0m 
[38;5;245m│[0m .PHONY: build
[38;5;245m│[0m build:
[38;5;245m│[0m 	@echo "building"
[38;5;245m│[0m 	hugo -d ${OUTPUT_DIR}
[38;5;245m│[0m 
[38;5;245m│[0m .PHONY: commit
[38;5;245m│[0m commit:
[38;5;245m│[0m 	git -C ${OUTPUT_DIR} add -A
[38;5;245m│[0m 	git -C ${OUTPUT_DIR} commit -m "Deploy: $(shell date)"
[38;5;245m│[0m 	git -C ${OUTPUT_DIR} push origin master
[38;5;245m│[0m 
[38;5;245m│[0m .PHONY: deploy
[38;5;245m│[0m deploy: clean build commit
[38;5;245m│[0m 
[38;5;245m│[0m .PHONY: server
[38;5;245m│[0m server:
[38;5;245m│[0m 	hugo -D server
[38;5;244m┄──────────────────────────────────────────────────────────────────────────────[0m

Stay safe :P

[38;5;244m└─[0m [38;5;40m→[0m view online: [38;5;40mhttps://joaocosta.dev/blog/5[0m
