クラス図 チートシート

Get original Markdown
classDiagram
class Vehicle
class SUV
class Rotatable { <<interface>> }
class Motor
Vehicle         <|--        SUV :          is a
(汎化) Rotatable <|.. Motor : implements
(実現)
classDiagram
class Microphone
class Speaker
class Engine
class Transmission
Microphone      --          Speaker :      are associated
(関連) Engine <--> Transmission : are interdependent
(双方向関連)
classDiagram
class TempSensor
class TempGauge
class Battery
class Wiper
TempSensor      <--         TempGauge :    refers to
(単方向関連) Battery "1" <.. "*" Wiper : uses
(一時的依存)
classDiagram
class Door
class Window
class Car
class Tire
Door       "1"  *-- "1..2"  Window :       composes
(コンポジション) Car "1" o-- "4..5" Tire : belongs to
(集約)
記法 結合度 用語 読み方 説明
--|> 汎化 is a(〜である) 継承関係。サブクラスがスーパークラスの機能を継承する。逆から見れば汎化関係。
..|> 実現 implements(実装する) インターフェースの実装。言語によってはインターフェース名にIを付ける(例:IMotor)。
-- 関連 are associated(互いに関連している) 何らかの関係性。方向が曖昧なため非推奨。
<--> 双方向関連 are interdependent(互いに結びついている) 双方向の関係。互いに参照し合う。疎結合にするにはインターフェースを導入する。
--> 単方向関連 refers to(参照する) 単方向の関係。参照する側 → 参照される側。
..> 一時的依存 uses(使用する) 一時的な依存関係。使用するが所有はしない。
--* コンポジション composes(構成する) 強い所有関係。全体が破壊されると部分も破壊される。
--o 集約 belongs to(所属する) 弱い所有関係。全体が破壊されても部分は残る。関係性が曖昧なため非推奨。

1. 汎化 (Generalization) - is a

記法 結合度 用語 読み方 説明
--|> 汎化 is a(〜である) 継承関係。サブクラスがスーパークラスの機能を継承する。逆から見れば汎化関係。
classDiagram
class Vehicle
class SUV
Vehicle <|-- SUV : is a (汎化)
#include <iostream>
using namespace std;

// 汎化: SUVは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();     // Vehicleから継承
  suv.offRoad();
  return 0;
}
// 汎化: SUVはVehicleである
class Vehicle {
  move() {
    console.log("Vehicle moving");
  }
}

class SUV extends Vehicle {
  offRoad() {
    console.log("SUV off-roading");
  }
}

const suv = new SUV();
suv.move();     // Vehicleから継承
suv.offRoad();
# 汎化: SUVはVehicleである
class Vehicle:
  def move(self):
    print("Vehicle moving")

class SUV(Vehicle):
  def off_road(self):
    print("SUV off-roading")

suv = SUV()
suv.move()      # Vehicleから継承
suv.off_road()

2. 実現 (Realization) - implements

記法 結合度 用語 読み方 説明
..|> 実現 implements(実装する) インターフェースの実装。言語によってはインターフェース名にIを付ける(例:IMotor)。
classDiagram
class Rotatable { <<interface>> }
class Motor
Rotatable <|.. Motor : implements (実現)
#include <iostream>

using namespace std;

// 実現: Motorはインターフェース Rotatable を実装する
class Rotatable {
public:
  virtual void rotate() = 0;  // 純粋仮想関数(インターフェース)
  virtual ~Rotatable() {}
};

class Motor : public Rotatable {
public:
  void rotate() override {
    cout << "Motor rotating" << endl;
  }
};

int main() {
  Motor motor;
  motor.rotate();
  return 0;
}
// 実現: Motorはインターフェース Rotatable を実装する

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

# 実現: Motorはインターフェース Rotatable を実装する

class Rotatable(ABC):
  @abstractmethod
  def rotate(self):
    pass

class Motor(Rotatable):
  def rotate(self):
    print("Motor rotating")

motor = Motor()
motor.rotate()

3. 双方向関連 (Bidirectional Association) - are interdependent

記法 結合度 用語 読み方 説明
<--> 双方向関連 are interdependent(互いに結びついている) 双方向の関係。互いに参照し合う。疎結合にするにはインターフェースを導入する。
classDiagram
class Engine
class Transmission
Engine <--> Transmission : are interdependent (双方向関連)
#include <iostream>

using namespace std;

class Transmission;

// 双方向関連: EngineとTransmissionは互いに参照し合う
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;
}
// 双方向関連: EngineとTransmissionは互いに参照し合う

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();
# 双方向関連: EngineとTransmissionは互いに参照し合う

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()

4. 単方向関連 (Directed Association) - refers to

記法 結合度 用語 読み方 説明
--> 単方向関連 refers to(参照する) 単方向の関係。参照する側 → 参照される側。
classDiagram
class TempSensor
class TempGauge
TempSensor <-- TempGauge : refers to (単方向関連)
#include <iostream>

using namespace std;

// 単方向関連: TempGaugeは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;
}
// 単方向関連: TempGaugeは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();
# 単方向関連: TempGaugeは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()

5. 一時的依存 (Temporal Dependency) - uses

記法 結合度 用語 読み方 説明
..> 一時的依存 uses(使用する) 一時的な依存関係。使用するが所有はしない。
classDiagram
class Battery
class Wiper
Battery "1" <.. "*" Wiper : uses (一時的依存)
#include <iostream>

using namespace std;

// 一時的依存: WiperはBatteryを一時的に使用する
class Battery {
public:
  void providePower() {
    cout << "Battery providing power" << endl;
  }
};

class Wiper {
public:
  void wipe(Battery& battery) {  // 使用するが所有しない
    battery.providePower();
    cout << "Wiper wiping" << endl;
  }
};

int main() {
  Battery battery;
  Wiper wiper;
  wiper.wipe(battery);  // 一時的な使用
  return 0;
}
// 一時的依存: WiperはBatteryを一時的に使用する

class Battery {
  providePower() {
    console.log("Battery providing power");
  }
}

class Wiper {
  wipe(battery) {  // 使用するが所有しない
    battery.providePower();
    console.log("Wiper wiping");
  }
}

const battery = new Battery();
const wiper = new Wiper();
wiper.wipe(battery);  // 一時的な使用
# 一時的依存: WiperはBatteryを一時的に使用する

class Battery:
  def provide_power(self):
    print("Battery providing power")

class Wiper:
  def wipe(self, battery):  # 使用するが所有しない
    battery.provide_power()
    print("Wiper wiping")

battery = Battery()
wiper = Wiper()
wiper.wipe(battery)  # 一時的な使用

6. コンポジション (Composition) - composes

記法 結合度 用語 読み方 説明
--* コンポジション composes(構成する) 強い所有関係。全体が破壊されると部分も破壊される。
classDiagram
class Door
class Window
Door "1" *-- "1..2" Window : composes (コンポジション)
#include <iostream>

using namespace std;

// コンポジション: DoorはWindowを所有する(強い所有関係)
class Window {
public:
  Window() { cout << "Window created" << endl; }
  ~Window() { cout << "Window destroyed" << endl; }
  void open() { cout << "Window opening" << endl; }
};

class Door {
private:
  Window window;  // Doorに所有される
public:
  Door() { cout << "Door created" << endl; }
  ~Door() { cout << "Door destroyed" << endl; }
  void openWindow() { window.open(); }
};

int main() {
  {
    Door door;
    door.openWindow();
  }  // Doorが破壊される → Windowも自動的に破壊される
  cout << "End of program" << endl;
  return 0;
}
// コンポジション: DoorはWindowを所有する(強い所有関係)

class Window {
  constructor() {
    console.log("Window created");
  }

  open() {
    console.log("Window opening");
  }
}

class Door {
  constructor() {
    console.log("Door created");
    this.window = new Window();  // Doorに所有される
  }

  openWindow() {
    this.window.open();
  }
}

const door = new Door();
door.openWindow();
// doorがガベージコレクションされると、windowも回収される
# コンポジション: DoorはWindowを所有する(強い所有関係)

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()  # Doorに所有される

  def __del__(self):
    print("Door destroyed")

  def open_window(self):
    self.window.open()

door = Door()
door.open_window()
del door  # Doorが破壊される → Windowも自動的に破壊される
print("End of program")