UML Class Diagram
Class diagrams are part of UML (Unified Modeling Language), which is a standardized graphical representation for specifying, visualizing, constructing, and documenting the artifacts of software systems. In class diagrams, various types of arrows are used to depict relationships between classes.
It’s kind of boring, business-like stuff, but it’s important to know the basics of UML class diagrams. They are used in many places, including design documents, code reviews, and technical interviews. Any complex system should probably be documented with UML diagrams, but for small projects, it’s usually enough to have a basic understanding of class diagrams.
They’re really important for understanding and representing design patterns and object-oriented concepts like inheritance, polymorphism, and encapsulation.
I always find the arrows and relationships in class diagrams hard to remember so here’s a quick refresher.
The most commonly used relationships and arrows:
1. Association (—)
- Description: Association represents a “using” relationship between two or more classes. It establishes a connection between the classes.
- Java Example: In the following code, the
Person
class uses theAddress
class. This is an example of a simple association.
public class Address {
String street;
String city;
// methods...
}
public class Person {
Address address;
// methods...
}
2. Aggregation (◇—)
- Description: Aggregation is a specialized form of association, representing a “whole-part” or “a-part-of” relationship. It indicates that one class contains another class.
- Java Example: A
Library
class contains manyBook
instances.
import java.util.List;
public class Book {
String title;
// methods...
}
public class Library {
List<Book> books;
// methods...
}
3. Composition (◆—)
- Description: Composition is a stronger form of aggregation. It indicates not only a “whole-part” relationship but also specifies that the part cannot exist without the whole.
- Java Example: In a
Computer
class, theCPU
andMemory
components can’t exist without theComputer
.
public class CPU {
// methods...
}
public class Memory {
// methods...
}
public class Computer {
CPU cpu = new CPU();
Memory memory = new Memory();
// methods...
}
4. Inheritance (▷—)
- Description: Inheritance depicts an “is-a” relationship between the base class (parent) and the derived class (child).
- Java Example: A
Vehicle
class can be a parent class, andCar
andBike
classes can be its children.
public class Vehicle {
// methods...
}
public class Car extends Vehicle {
// methods...
}
public class Bike extends Vehicle {
// methods...
}
5. Dependency (←——)
- Description: Dependency represents a “uses” relationship between two classes where one class depends on another temporarily.
- Java Example: A
Driver
class depends on theLicense
class to perform thedrive()
operation.
public class License {
// methods...
}
public class Driver {
public void drive(License license) {
// methods...
}
}
6. Realization (⇒)
- Description: Realization represents a relationship where a class implements an interface.
- Java Example: A
Bird
class can implement theFlyable
interface.
public interface Flyable {
void fly();
}
public class Bird implements Flyable {
public void fly() {
// implementation
}
}
In class diagrams, these arrows help to quickly understand the relationships and dependencies between classes, making it easier to read and maintain the code.
House Example
Here’s a simple example of a class diagram showing the main relationships between classes:
// Association: A House has a Door (but a Door can exist independently)
class Door {
// ...
}
// Aggregation: A House has multiple Windows (but Windows can exist independently)
class Window {
// ...
}
// Composition: A House has multiple Rooms (and Rooms cannot exist without a House)
class Room {
// ...
}
// Inheritance: An Apartment is a type of House
class Apartment extends House {
// ...
}
// Dependency: House uses Electricity (but they are not permanently tied)
class Electricity {
// ...
}
// Realization: House must adhere to the BuildingCode interface
interface BuildingCode {
void adhereToCode();
}
class House implements BuildingCode {
Door door;
List<Window> windows;
List<Room> rooms;
@Override
public void adhereToCode() {
// implementation
}
// Dependency example
public void consumeElectricity(Electricity electricity) {
// ...
}
}
// Usage
public class Main {
public static void main(String[] args) {
// Composition
House house = new House();
Room room1 = new Room();
Room room2 = new Room();
house.rooms = Arrays.asList(room1, room2);
// Aggregation
Window window1 = new Window();
Window window2 = new Window();
house.windows = Arrays.asList(window1, window2);
// Association
Door door = new Door();
house.door = door;
// Dependency
Electricity electricity = new Electricity();
house.consumeElectricity(electricity);
// Inheritance and Realization are evident from the class definitions
}
}