Class Diagrams – Part 1

Class Diagrams – Part 1

Reading Time: ~ 6 minutes

Hello my esteemed fellow Softects (Software + Architects… maybe it will stick). Today I would like to discuss Class Diagrams. If you want to talk software architecture it is good to have a common way of express ideas. Now UML is really extensive and somewhat flexible and thus I am a believer that the Pareto Principle (or 80/20 Rule if you will) should be applied. What I mean is: Learn that 20% of the tools that will help you on 80% of the cases.

Class Diagrams

Class Diagrams are a good tool to show how the Classes or Objects of the system relate to each other in a static way. This can give you a good overview on your dependencies.

There is a lot that one can talk about class diagrams and I am definitely not going to do a deep-dive here (remember: Pareto principle). But there is still a lot to cover and I have split this in two parts to be more easily digested. So check part 2!

Note: Throughout this post I’ll be using the PlantUML renderer. This might, in some places, give a different representation than the one in the original UML, but this should not prevent the understanding of the concept.

When to use?

Class Diagrams should be used when you need to explain dependencies, describe the way classes and modules are structured or if you are trying to understand how the parts in a system relate. They are not, as any other tool, a one-for-all tool. There are other moments, such as when understanding  the flow of information, when you have to make use of other tools which we will cover in other posts.

Basic Components

The Class in Class Diagram

To represent a class, we use a rectangle. Using PlantUML it shows a “C” on it symbolizing it is a class (it can be an interface, enum, etc) but that is not strictly a requirement of UML.

PlantUML Syntax:<br />
class MyClass {<br />
}<br />
Hide Methods<br />
Hide Members<br />

The class representation may carry more information, but we will get to those. Right now you should notice that the rectangle has the name of the class and that is pretty much it.

Attributes

Let’s expand our previous class representation!

Now most of the classes have attributes/fields inside, i.e. information that it is carrying around with it to perform its tasks. We can represent these in UML by only the name of the attribute:

PlantUML Syntax:<br />
class MySimpleClass {<br />
anAttribute<br />
}<br />
Hide Methods<br />

 OR by adding a bunch of information in such a form:

visibility name: type multiplicity = default {property string}

PlantUML Syntax:<br />
class MyCompleteClass {<br />
+ anAttribute: String [1] = “DefaultName” {readOnly}<br />
}<br />
Hide Methods<br />

Now that is a LOT of information! As mentioned before, just the name is required, but if you want more you have to use your own discretion on the amount of information you are putting on your class diagrams.

Let’s go through the elements of the attribute:

Visibility

There are 4 different types of visibility modifiers: public, private, protected and package-private.

The two you might most see/use are the public and private. The others might not make sense to represent (no need to expose an internal variable, unless you want of course) or are just not used at all.

Class Diagrams visibility attribute
Visibility representation in plantUML

Type

It is the restriction you put on which type of object this attribute can be. If you think about it from a programming perspective this is the type of the attribute. If you do that, then this is of course language dependent and might be a primitive of the system (String/int/boolean in Java) or another object/data structure.

Multiplicity

This is an indication of how many of that object type can fill the attribute. List for example can contain many, however a single boolean  can only hold, well you’ve guessed: 1 value!

Usually multiplicity is defined with a lower bound (a minimum value from 0 to any positive number) and an upper bound (a maximum value any positive number or * for unlimited). These are usually not used on attribute description but when representing the attributes as its own square (opposed to inside the class). We will see this in a bit.

The most common values you will see are:

  • 1 (ex.: a car has 1 owner)
  • 0..1 (ex.: An owner can own none or one car)
  • * (ex.: a car factory can own zero or more cars)

Default Value

This is the value the attribute will receive unless otherwise specified such as in a setter or constructor.

Property String

This just allows you to indicate any additional information for the attribute you might need.

 

Associations

Now there is another way you might see attributes being represented in Class Diagrams and that is by using associations.

This basically denotes the same thing than before but it makes use of another rectangle instead of adding it directly to the class description:

PlantUML Syntax:<br />
class MyAttributesClass {<br />
+ anAttribute: String [1] = “DefaultName” {readOnly}<br />
}<br />
Hide Methods<br />

PlantUML Syntax:<br />
MyAssociationsClass -> “1” String: +anAttribute<br />
Hide Methods<br />
Hide Members<br />

Both of these are equivalent an convey the same idea. You have to decide which one you think it is the best. I for once prefer to keep primitives as attributes and complex objects or data structures as associations

The arrows on associations show the source and target, i.e. which one is the owner and which one is the attribute (arrow from and to, respectively).

Bidirectional Associations

Associations can also be bidirectional. We saw before unidirectional associations, however in your designing of systems you may come across a situation where you need to have a bidirectional association such as:

PlantUML Syntax:<br />
Person “0..1” <—> “*” Car<br />
Hide circle<br />
Hide Methods<br />
Hide Members<br />


PlantUML Syntax:<br />
Car – Person: < owns<br />
Hide circle<br />
Hide Methods<br />
Hide Members<br />

On both cases we have the situation where Car contains a Person attribute (an owner) and a Person has a Car attribute, hence the bidirectional association.

On the second case you are naming your association. Now I find that I only use this IF this actually adds understanding, i.e. value, to the diagram. Else I just leave it out!

 

Operations

Operations are actions that a class knows to perform. These can be considered like functions or methods in programming.

Normally, any operations like getters or setters are not shown, since they can be inferred and do not add value to the Class Diagrams. But any other action you assume it is useful for your audience can be added here.

As with operations here is the full syntax:

visibility name (parameter-list) : return type {property string}

And here is an example of it in UML:

PlantUML Syntax:<br />
class MyClass {<br />
+ anAttribute: String<br />
-anotherPrivateAttribute : int<br />
~method1()<br />
+method2(int) : int<br />
}<br />

note how we put these operations in the second compartment of the rectangle!

Now let’s go through the parameters:

Visibility

Just as before there are 4 different types of visibility modifiers: public, private, protected and package-private.

Here is the image again just so you don’t have to scroll up again (you’re welcome)

Class Diagrams visibility attribute
Visibility representation in plantUML

Name

Simply the name of the method. No complications here!

Parameter-list

The list of parameters/inputs you are passing to this operation. This can be empty or a huge list (please don’t do a huge list, it is a code smell… use Builders or Wrappers).

These are notated similar to attributes. Like:

direction name: type = default

Name, type and default were already covered, however direction is new. Direction simply denotes if it is an input or output. These are denoted with a ‘+’ and a ‘-‘ respectively.

If there is no direction given it is assumed to be an input. (It is usually seen like this!)

Return Type

This is the type of the value that will be returned (if any) to the user/action calling this operation.

Property String

Same as before: it allows you to indicate any additional information for the attribute you might need

 

Wrapping up Class Diagrams (Part 1)

As mentioned before this will be continued: check part 2 here.

We saw:

  • the basics of a Class Diagram component.
  • showing operations
  • representing attributes:
    • inside the class object
    • as an association

This might surprise you but this would take you a LONG way already! On the next part you will learn a bit more about Generalization, Constrains and Notes on the Class Diagram.

Some last remarks

There is a lot of information you can put into a UML representation. Class diagrams are no exception and can get extremely packed of information pretty quick. Try to be reasonable when adding these and remember:

  • Not everything needs to be depicted; avoid naming every association, avoid adding all the info for each attribute, etc.
  • Not every part of the system must be on the representation; If it is not necessary for the understanding, leave it out.
  • Remember the golden rule: “If it doesn’t add value to the explanation of the system, leave it out!”
  • Finally: don’t care about any of these suggestions: if you judge it necessary do it! You are the architect!

 

Yours truly,

Archie

Leave your opinion, start a discussion, share an experience or just a compliment...

%d bloggers like this: