classDiagram
class Vehicle
class SUV
class Rotatable { <<interface>> }
class Motor
Vehicle <|-- SUV : is a
(Generalization)
Rotatable <|.. Motor : implements
(Realization)
classDiagram
class Microphone
class Speaker
class Engine
class Transmission
Microphone -- Speaker : are associated
(Association)
Engine <--> Transmission : are interdependent
(Bidirectional
Association)
classDiagram
class TempSensor
class TempGauge
class Battery
class Wiper
TempSensor <-- TempGauge : refers to
(Directed
Association)
Battery "1" <.. "*" Wiper : uses
(Temporary
Dependency)
classDiagram
class Door
class Window
class Car
class Tire
Door "1" *-- "1..2" Window : composes
(Composition)
Car "1" o-- "4..5" Tire : belongs to
(Aggregation)
| Notation | Coupling | Term | Reading | Explanation |
|---|---|---|---|---|
--|> |
High | Generalization / Specialization |
is a | A subclass inherits functionality from a superclass; conversely, a generalization relationship. |
..|> |
Low | Realization | implements | Implementation of an interface; some languages prefix interfaces with I, e.g., IMotor. |
-- |
Mid | Association | are associated | Some kind of relationship; direction is ambiguous, so not recommended. |
<--> |
High | Bidirectional Association |
are inter- dependent |
Bidirectional relationship; they reference each other; introduce an interface to achieve loose coupling. |
--> |
Mid | Directed Association |
refers to | Unidirectional relationship; the referrer → the referent. |
..> |
Low | Temporary Dependency |
uses | Temporary dependency; uses but does not own. |
--* |
High | Composition | composes | Strong ownership; when the whole is destroyed, the parts are also destroyed. |
--o |
Mid | Aggregation | belongs to | Weak ownership; parts remain if the whole is destroyed; relationship is ambiguous, so not recommended. |
| Notation | Coupling | Term | Reading | Explanation |
|---|---|---|---|---|
--|> |
High | Generalization / Specialization |
is a | A subclass inherits functionality from a superclass; conversely, a generalization relationship. |
classDiagram
class Vehicle
class SUV
Vehicle <|-- SUV : is a
#include <iostream>
using namespace std;
// Generalization: SUV is a Vehicle
class Vehicle {
public:
void move() {
cout << "Vehicle moving" << endl;
}
};
class SUV : public Vehicle {
public:
void offRoad() {
cout << "SUV off-roading" << endl;
}
};
int main() {
SUV suv;
suv.move(); // inherited from Vehicle
suv.offRoad();
return 0;
}
// Generalization: SUV is a Vehicle
class Vehicle {
move() {
console.log("Vehicle moving");
}
}
class SUV extends Vehicle {
offRoad() {
console.log("SUV off-roading");
}
}
const suv = new SUV();
suv.move(); // inherited from Vehicle
suv.offRoad();
# Generalization: SUV is a Vehicle
class Vehicle:
def move(self):
print("Vehicle moving")
class SUV(Vehicle):
def off_road(self):
print("SUV off-roading")
suv = SUV()
suv.move() # inherited from Vehicle
suv.off_road()
| Notation | Coupling | Term | Reading | Explanation |
|---|---|---|---|---|
..|> |
Low | Realization | implements | Implementation of an interface; some languages prefix interfaces with I, e.g., IMotor. |
classDiagram
class Rotatable { <<interface>> }
class Motor
Rotatable <|.. Motor : implements
#include <iostream>
using namespace std;
// Realization: Motor implements Rotatable interface
class Rotatable {
public:
virtual void rotate() = 0; // pure virtual function (interface)
virtual ~Rotatable() {}
};
class Motor : public Rotatable {
public:
void rotate() override {
cout << "Motor rotating" << endl;
}
};
int main() {
Motor motor;
motor.rotate();
return 0;
}
// Realization: Motor implements Rotatable interface
class Rotatable {
rotate() {
throw new Error("Must implement rotate()");
}
}
class Motor extends Rotatable {
rotate() {
console.log("Motor rotating");
}
}
const motor = new Motor();
motor.rotate();
from abc import ABC, abstractmethod
# Realization: Motor implements Rotatable interface
class Rotatable(ABC):
@abstractmethod
def rotate(self):
pass
class Motor(Rotatable):
def rotate(self):
print("Motor rotating")
motor = Motor()
motor.rotate()
| Notation | Coupling | Term | Reading | Explanation |
|---|---|---|---|---|
<--> |
High | Bidirectional Association |
are inter- dependent |
Bidirectional relationship; they reference each other; introduce an interface to achieve loose coupling. |
classDiagram
class Engine
class Transmission
Engine <--> Transmission : are interdependent
#include <iostream>
using namespace std;
class Transmission;
// Bidirectional Association: Engine and Transmission reference each other
class Engine {
private:
Transmission* transmission;
public:
Engine() : transmission(nullptr) {}
void setTransmission(Transmission* t) { transmission = t; }
void run() { cout << "Engine running" << endl; }
};
class Transmission {
private:
Engine* engine;
public:
Transmission() : engine(nullptr) {}
void setEngine(Engine* e) { engine = e; }
void shift() { cout << "Transmission shifting" << endl; }
};
int main() {
Engine engine;
Transmission transmission;
engine.setTransmission(&transmission);
transmission.setEngine(&engine);
engine.run();
transmission.shift();
return 0;
}
// Bidirectional Association: Engine and Transmission reference each other
class Engine {
constructor() {
this.transmission = null;
}
setTransmission(transmission) {
this.transmission = transmission;
}
run() {
console.log("Engine running");
}
}
class Transmission {
constructor() {
this.engine = null;
}
setEngine(engine) {
this.engine = engine;
}
shift() {
console.log("Transmission shifting");
}
}
const engine = new Engine();
const transmission = new Transmission();
engine.setTransmission(transmission);
transmission.setEngine(engine);
engine.run();
transmission.shift();
# Bidirectional Association: Engine and Transmission reference each other
class Engine:
def __init__(self):
self.transmission = None
def set_transmission(self, transmission):
self.transmission = transmission
def run(self):
print("Engine running")
class Transmission:
def __init__(self):
self.engine = None
def set_engine(self, engine):
self.engine = engine
def shift(self):
print("Transmission shifting")
engine = Engine()
transmission = Transmission()
engine.set_transmission(transmission)
transmission.set_engine(engine)
engine.run()
transmission.shift()
| Notation | Coupling | Term | Reading | Explanation |
|---|---|---|---|---|
--> |
Mid | Directed Association |
refers to | Unidirectional relationship; the referrer → the referent. |
classDiagram
class TempSensor
class TempGauge
TempSensor <-- TempGauge : refers to
#include <iostream>
using namespace std;
// Directed Association: TempGauge refers to TempSensor
class TempSensor {
private:
int temperature;
public:
TempSensor() : temperature(25) {}
int getTemperature() { return temperature; }
};
class TempGauge {
private:
TempSensor* sensor;
public:
TempGauge(TempSensor* s) : sensor(s) {}
void display() {
cout << "Temperature: " << sensor->getTemperature() << "C" << endl;
}
};
int main() {
TempSensor sensor;
TempGauge gauge(&sensor);
gauge.display();
return 0;
}
// Directed Association: TempGauge refers to TempSensor
class TempSensor {
constructor() {
this.temperature = 25;
}
getTemperature() {
return this.temperature;
}
}
class TempGauge {
constructor(sensor) {
this.sensor = sensor;
}
display() {
console.log(`Temperature: ${this.sensor.getTemperature()}C`);
}
}
const sensor = new TempSensor();
const gauge = new TempGauge(sensor);
gauge.display();
# Directed Association: TempGauge refers to TempSensor
class TempSensor:
def __init__(self):
self.temperature = 25
def get_temperature(self):
return self.temperature
class TempGauge:
def __init__(self, sensor):
self.sensor = sensor
def display(self):
print(f"Temperature: {self.sensor.get_temperature()}C")
sensor = TempSensor()
gauge = TempGauge(sensor)
gauge.display()
| Notation | Coupling | Term | Reading | Explanation |
|---|---|---|---|---|
..> |
Low | Temporary Dependency |
uses | Temporary dependency; uses but does not own. |
classDiagram
class Battery
class Wiper
Battery "1" <.. "*" Wiper : uses
#include <iostream>
using namespace std;
// Temporal Dependency: Wiper uses Battery temporarily
class Battery {
public:
void providePower() {
cout << "Battery providing power" << endl;
}
};
class Wiper {
public:
void wipe(Battery& battery) { // uses but does not own
battery.providePower();
cout << "Wiper wiping" << endl;
}
};
int main() {
Battery battery;
Wiper wiper;
wiper.wipe(battery); // temporary usage
return 0;
}
// Temporal Dependency: Wiper uses Battery temporarily
class Battery {
providePower() {
console.log("Battery providing power");
}
}
class Wiper {
wipe(battery) { // uses but does not own
battery.providePower();
console.log("Wiper wiping");
}
}
const battery = new Battery();
const wiper = new Wiper();
wiper.wipe(battery); // temporary usage
# Temporal Dependency: Wiper uses Battery temporarily
class Battery:
def provide_power(self):
print("Battery providing power")
class Wiper:
def wipe(self, battery): # uses but does not own
battery.provide_power()
print("Wiper wiping")
battery = Battery()
wiper = Wiper()
wiper.wipe(battery) # temporary usage
| Notation | Coupling | Term | Reading | Explanation |
|---|---|---|---|---|
--* |
High | Composition | composes | Strong ownership; when the whole is destroyed, the parts are also destroyed. |
classDiagram
class Door
class Window
Door "1" *-- "1..2" Window : composes
#include <iostream>
using namespace std;
// Composition: Door owns Window (strong ownership)
class Window {
public:
Window() { cout << "Window created" << endl; }
~Window() { cout << "Window destroyed" << endl; }
void open() { cout << "Window opening" << endl; }
};
class Door {
private:
Window window; // owned by Door
public:
Door() { cout << "Door created" << endl; }
~Door() { cout << "Door destroyed" << endl; }
void openWindow() { window.open(); }
};
int main() {
{
Door door;
door.openWindow();
} // Door destroyed -> Window automatically destroyed
cout << "End of program" << endl;
return 0;
}
// Composition: Door owns Window (strong ownership)
class Window {
constructor() {
console.log("Window created");
}
open() {
console.log("Window opening");
}
}
class Door {
constructor() {
console.log("Door created");
this.window = new Window(); // owned by Door
}
openWindow() {
this.window.open();
}
}
const door = new Door();
door.openWindow();
// When door is garbage collected, window is also collected
# Composition: Door owns Window (strong ownership)
class Window:
def __init__(self):
print("Window created")
def __del__(self):
print("Window destroyed")
def open(self):
print("Window opening")
class Door:
def __init__(self):
print("Door created")
self.window = Window() # owned by Door
def __del__(self):
print("Door destroyed")
def open_window(self):
self.window.open()
door = Door()
door.open_window()
del door # Door destroyed -> Window automatically destroyed
print("End of program")