オブジェクト指向プログラミング(OOP)は、堅牢で保守性の高いJavaアプリケーションの礎です。OOPの重要な概念であるコンポジションとアグリゲーションは、しばしば混乱を招きます。どちらもオブジェクト間の「has-a」関係を表しますが、その意味と使用方法においては大きく異なります。この記事では、実践的な例を通してこれらの違いを明確にします。
目次
Javaにおけるコンポジション
「強い」has-a関係であるコンポジションは、部品のライフサイクルが全体に完全に依存する全体と部分の関係を表します。全体の破壊は、その部分も破壊します。部分は独立して存在できません。車を考えてみましょう。車はエンジン、車輪、ドアなどで構成されています。車を廃棄すると、これらの部品も処分されます。
Javaでは、コンポジションは通常、全体オブジェクトのクラス内で部分オブジェクトを直接インスタンス化することによって実装されます。全体オブジェクトはこれらの部分を生成して管理します。
Javaにおけるアグリゲーション
「弱い」has-a関係であるアグリゲーションは、部品が全体とは独立して存在できることを示します。全体オブジェクトは部品への参照を保持しますが、それらのライフサイクルは直接リンクされていません。例えば、大学は学部を「持っていますが」、大学が閉鎖されても学部は存続します。
Javaでは、アグリゲーションは、全体オブジェクトが部分オブジェクトへの参照を保持することを伴います。これらの参照は別々に管理できます。部分は全体オブジェクトの前または後に作成でき、その破壊後も存続します。
コンポジション vs. アグリゲーション
下記の表は、主な違いをまとめたものです。
特徴 | コンポジション | アグリゲーション |
---|---|---|
関係 | 強い「has-a」(全体と部分) | 弱い「has-a」 |
ライフサイクル | 部分のライフサイクルは全体のライフサイクルに依存する | 部分のライフサイクルは全体のライフサイクルに依存しない |
所有権 | 全体オブジェクトが部分の所有と管理を行う | 全体オブジェクトが部分への参照を保持する |
部分の存在 | 部分は独立して存在できない | 部分は独立して存在できる |
実装 | 全体オブジェクト内での直接的なインスタンス化 | 独立した部分オブジェクトへの参照 |
Javaにおけるコンポジションの使い方
エンジンで構成されるCar
を使用して、コンポジションを説明しましょう。
class Engine {
public void start() { System.out.println("Engine started"); }
}
class Car {
private Engine engine;
public Car() {
this.engine = new Engine();
}
public void drive() {
engine.start();
System.out.println("Car driving");
}
}
public class Main {
public static void main(String[] args) {
Car myCar = new Car();
myCar.drive();
}
}
Engine
オブジェクトはCar
クラス内で作成されます。Engine
の存在はCar
に依存します。
Javaにおけるアグリゲーションの使い方
次に、大学とその学部を使用してアグリゲーションを説明しましょう。
class Department {
private String name;
public Department(String name) { this.name = name; }
public String getName() { return name; }
}
class University {
private Department[] departments;
public University(Department[] departments) {
this.departments = departments;
}
public void printDepartments() {
for (Department dept : departments) {
System.out.println("Department: " + dept.getName());
}
}
}
public class Main {
public static void main(String[] args) {
Department cs = new Department("Computer Science");
Department math = new Department("Mathematics");
Department[] deps = {cs, math};
University uni = new University(deps);
uni.printDepartments();
}
}
University
はDepartment
オブジェクトへの参照を保持します。Department
オブジェクトは独立して存在し、他の場所で使うことができます。
コンポジションとアグリゲーションを理解することで、より堅牢で保守性の高く、構造化されたJavaアプリケーションを設計できます。どちらを選択するかは、設計要件とオブジェクトの望ましいライフサイクル管理によって異なります。