UML

4 minute read

Association -> Aggregation -> Composition

Wikipedia : Sometimes aggregation is referred to as composition when the distinction between ordinary composition and aggregation is unimportant.

Association: “can-call” - connection between classes, like a friendship.

Aggregation: “has-a” relationship, where one class has (but doesn’t own) instances of another class.

composition: “composed of” relationship (Whole-Part), where one class is composed of (and owns) instances of another class.

Association:

https://www.uml-diagrams.org/association.html?context=class-diagrams

  • General relationship
  • No specific ownership or lifecycle dependency
  • One-to-one, one-to-many, or many-to-many
  • Represented by a simple line connecting classes

For example, a Department class may be associated with an Employee class to represent that employees belong to different departments.

Has-A Relationship: Composition vs. Aggregation

Composition and Aggregation both represent a “has-a” relationship between classes, but they differ in ownership and dependency.

Aggregation (Empty Diamond)

  • Special form of association
  • “Whole-part” relationship
  • Weaker ownership: The part class is less tightly bound to the whole class.
  • Dependency: Parts can exist independently and be shared among multiple containing classes.
  • Example: A University “has-a” Department. Departments may continue to exist independently even if the University closes.

Example: A Car class may have wheels, where wheels are parts of the car but can exist independently.

// Contained class
public class Wheel {
    // Attributes and methods of the wheel
}

// Containing class
public class Car {
    private final List<Wheel> wheels; // Aggregation relationship

    public Car(List<Wheel> wheels) {
        this.wheels = wheels; // Assigning wheels passed as parameter
    }
}

Composition (Filled-in Diamond ◆)

  • Also known as whole-part relationship
  • Has-a relationship
  • Strong ownership: The part class is tightly bound to the whole class.
  • Part class’s lifecycle is controlled by the whole class
  • Indicated by a filled diamond (◆)

Example: A House class may have rooms, where rooms are parts of the house and cannot exist without the house. If the House is destroyed, Rooms cease to exist.

// Contained class
public class Engine {
    // Attributes and methods of the engine
}

// Containing class
public class Car {
    private final Engine engine; // Composition relationship

    public Car() {
        this.engine = new Engine(); // Creating engine instance within Car
    }
}

Generalization/Inheritance - IS-A (Empty Arrowhead):

  • Denoted by an empty arrowhead pointing from the subclass to the superclass.
  • Indicates an “is-a” relationship.
  • Subclass inherits attributes and behaviors from the superclass.

  • The Is-A relationship test is also known as INHERITANCE test.
  • IS-A: The property of an object being an instance of a data type.
  • This holds true for a child that is a subclass of any parent, be it a direct subclass or a distant child.
  • We use the multi-inheritance property of interfaces to preserve the IS-A relationship.
  • For example, a Cat is an Animal, and a Cat is also a Pet.

Generalization/Inheritance represents an “is-a” relationship, where the subclass inherits attributes and behaviors from the superclass. It’s denoted by an empty arrowhead pointing from the subclass (child) to the superclass (parent).

For example, if class Car inherits from class Vehicle, you would draw a line with an empty arrowhead from Car to Vehicle.

// Parent class
public class Vehicle {
    // Attributes and methods common to all vehicles
}

// Child class inheriting from Vehicle
public class Car extends Vehicle {
    // Additional attributes and methods specific to cars
}

Dependency (Dashed Line with Arrow):

  • Denoted by a dashed line with an arrow pointing from the dependent class to the independent class.
  • Represents a using or “uses-a” relationship, where one class depends on another class for its implementation.
  • Dependencies are typically indicated by method parameters, local variables, or return types.

For example, if class A depends on class B, you would draw a dashed line with an arrow from class A to class B.

// Dependent class
public class Car {
    public void drive(Engine engine) { // Dependency on Engine class
        // Implementation of drive method using Engine
    }
}

Multiplicity:

  • Denotes the number of instances of one class related to the number of instances of another class.
  • Represented with a number at one end of the line and a “*” (asterisk) at the other end.

For example, “1” at one end and “*” at the other end of the line indicate that one instance of one class is related to zero or more instances of another class.

// Example of multiplicity in a relationship
public class Department {
    private final List<Employee> employees; // One-to-many relationship

    public Department(List<Employee> employees) {
        this.employees = employees;
    }
}

Using « » for Annotations:

  • Used to indicate properties or qualifiers of a relationship or dependency.
  • Often used with dependencies to specify the nature of the relationship, such as «interface», «implementation», «association», etc.

For example, if class A implements interface B, you would write “«implements»” near the dashed line between class A and interface B.

// Dependent class implementing an interface
public class Car implements Drivable { // <<implements>> annotation
    // Implementation of methods from Drivable interface
}

References

https://www.visual-paradigm.com/guide/uml-unified-modeling-language/uml-aggregation-vs-composition/

uml.png

Cheatsheet