In this second installment of Collaboration Artifacts I want to continue what was started with Use Case diagrams: advocate for more modeling activity in software development, while also offering some insights on UML as a foundation for this activity. Why? It simply pays off greatly to make mistakes early, clear out assumptions and make mistakes early (are you paying attention?) in a software development process.
I asked a friend of mine to proofread the Use Case article. I had not mentioned my plans to write more articles on UML when he gave me this gem of a comment:
PAP: I do hate Class and Object diagrams as they are too tied to a style of programming. But as you said, we can always ditch those we don’t like/need.
I was also motivated to see if could a least make a little of his dislike for Class and Object diagrams go away. I answered:
CØ: Challenge accepted! (As in, I will make you not hate it!)
What are Class diagrams?
So what is a Class diagram then? It is diagram notation for describing classes of information / objects and how they are related. A classic, simple example is the Car, which is a specialization of a Vehicle, and a Car has four wheels. A Truck could also be a specialization of Vehicle and have 18 wheels.
I feel the best way to dive in further would be to address the elephants in the room. I believe these elephants are why people turn away from Class and Object diagrams specifically and UML in general. They are:
- The purpose of Class diagrams is to eventually contain implementation details
- Class diagrams imply a Waterfall process
- UML cannot model a modern architecture
Elephant 1: The purpose of Class diagrams is to eventually contain implementation details
To address the first elephant, which relates to the misunderstanding that the goal of a Class diagram is to contain implementation details and full accuracy, we need to look at the purpose of a Class diagram.
The diagram exists as a Collaboration Artifact. This means it can and should be exchanged and discussed between team members and stakeholders. It is a way to visually document things we need to model in our system from the problem area and we will (hopefully) be doing so early in the process through interviews with stakeholders.
I was recently part of a digital transformation project at well known spirits producer. I will leave them unnamed, but think along the lines of Totally Rum. They wanted to store farming journals digitally and the farming journals were quite rich in information. I had no background in farming and neither did my team. I received several examples of these journals on paper, but they were different versions and contained different levels of detail. Discussions were abstract and there were a lot of questions about the scope of the data (how many farming activities should it contain, for example). To ensure correct understanding of the journals and the success of the project, I decided we needed an overview of this type of information. We started to create a Class diagram knowing we were in discovery mode and had to iterate.
The first versions existed simply to get an overview. All boxes, arrows and a little text. (this was reproduced from memory, so do not take these diagrams as fact) Note here that it was understood that these relationships meant composition, but we did not at this time go into adding multiplicity or similar details.
As we continued our discussions and the project moved forward, we added more information to the diagram and our understanding grew. We also completely misunderstood some things related to the farming journal. Still, making mistakes is great, because you will get taught again by your expert clients and your model of the information will be better.
Over time, the diagram was a great description of what we needed to model in our system – mostly conceptually, but also with a few fine details that we had to remember during implementation!
I highlight the word conceptually, because while we definitely had more and more details in the diagrams as we progressed, it was never our intent that the diagram should dictate implementation details. And here lies a very important lesson: There exist different types of Class diagrams!
I believe this crucial piece of information is lost on many. And I believe this is why UML diagrams rub developers the wrong way. It is assumed that the end goal of these diagrams is to achieve so much insight and detail, that it can dictate the implementation details, like in a waterfall development process. But that is not necessarily so. This depends on the project context – that is, in which phase you are in the project. And this is a great segue into discussing the next elephant.
Elephant 2: Class diagrams imply a Waterfall process
Yes, I did mention the project phase. Am I in any way suggesting a return to waterfall process-based projects? Most certainly not. But projects exist, it is just a fact of life. It does not matter if you follow Scrum or not, for example. Projects exist for the coordination of shared effort toward a feasible goal that has expected returns.
In some cases, say, while developing a SaaS product, we can discard the notion of a project. We can follow a Kanban and “no estimate” process because the entire team is working on the same thing and relatively in isolation. But more often than not, a product team does not work in isolation. Instead, there will be a need for coordination with other branches of the company or teams in other companies. The software product may have to be coordinated with governmental stakeholders and released with the introduction of new legislation (very hard deadlines).
Below is one of the best diagrams of a general project overview I have seen so far. Not really amazing visually (we’re back to the archaic look, sorry!), but it beautifully describes a project in two dimensions: Phases and activities. The diagram comes from the Unified Process (UP).
In the diagram above, you will recognize iterations (I1, E1, E2, C1, C2 etc.) – the process supports and emphasizes an iterative process. Also, it recognizes you will perform all activities to varying degrees, depending on where you are in the process. Because of this, it is safe to say that you are working in phases towards your goal, that can be identified and named: Inception, Elaboration, Construction, Transition.
A Class diagram made in the Elaboration phase are known to be design diagrams. They are about communication and understanding, and capturing what has been learned. In this phase it is encouraged to keep the diagrams at a higher level and it is perfectly fine to create a diagram that is good enough, neither perfect nor completely accurate.
This difference in Class diagrams was news to me when I studied UML in depth. No one had ever taught me this difference. This made so much sense and aligned with my personal outlook: we want to discover and learn new things about our expected end result as we go forward iteratively. And all of a sudden, working with UML was not in opposition to . Let me rephrase: A Class diagram can be extended and added to continuously, in any phase.
A quick note on the UP diagram above: UP advocates iterative software development and, as you can see, that all activities take place in all iterations in all phases. If you are somewhere on the spectrum of agile software development, the diagram should make sense to you. At the same time, there are over-arching phases in a project life-cycle that indicate to project members and stakeholders where we are in the overall delivery of the project from a helicopter perspective.
Elephant 3: UML cannot model a modern architecture
A lot has happened since UML was first defined in version 1.1 in 1997. It was recently updated in 2017, long after the inception of microservices and Domain-Driven Design. And while UML uses a different terminology, such as sub-systems and Classes, I do not believe they are in opposition. I will model my entities in UML Class diagrams without hesitation. Similarly, in Position Green, we successfully used a microservice approach to accommodate the specific needs of a client by adding a sub-system.
Domain-Driven Design specifies that an entity is also a transactional boundary. This just underlines how important it is to model your entities, and to do so iteratively with your domain experts. A Class diagram can go a long way towards making these discussions concrete.
What about the Object diagrams?
Class diagrams are great for communicating types of information and how they relate to each other. Nevertheless, it can be a bit abstract and sometimes we may ask ourselves, what will this really mean in practice? A great companion to answer this question is Object diagrams.
The purpose of the Object diagram is to model an example state of the Class diagram. An Object diagram of our earlier example of Vehicle, Car and wheels could be a Ford Bronco and four wheels. It could also be a Freightliner and its 18 wheels.
Object diagrams can be used in many cases, not only to exemplify state of a Class diagram, such as:
- Contents of a request and its response
- Payload of a Business Event
Class diagrams and object diagrams are great Collaboration Artifacts that bring value from the very beginning. They will help you weed out misunderstandings and assumptions, something that all participants in a project should strive for.
A few points on modeling a Class diagram:
- When creating Class diagrams please remember important learnings from the microservice movement and Domain-Driven Design.
Do not aim to make an all-encompassing model. Instead, split the model up within boundaries that follow the business. Also, deal with the ambiguity of the language as per recommendations in Domain.Driven-Design.
- While the examples above include inheritance, please use it sparingly. It’s worthy of an article on its own, but let’s just say that over time an inheritance can end up working against you, because the reality we try to model and implement is not as easily categorized into a tree (which is practically the result, as many programming language do not support multiple inheritance). Favor composition over inheritance.