集約と構成の概念的な違いを認識しています。例を使って、Javaの実装の違いを教えてもらえますか?
構成
final class Car {
private final Engine engine;
Car(EngineSpecs specs) {
engine = new Engine(specs);
}
void move() {
engine.work();
}
}
集計
final class Car {
private Engine engine;
void setEngine(Engine engine) {
this.engine = engine;
}
void move() {
if (engine != null)
engine.work();
}
}
合成の場合、エンジンは車によって完全にカプセル化されます。外部の世界がエンジンへの参照を取得する方法はありません。エンジンは車とともに生き、死にます。集約では、車はエンジンを介してその機能も実行しますが、エンジンは常に車の内部部品ではありません。エンジンは交換することも、完全に取り外すこともできます。それだけでなく、外の世界はまだエンジンへの参照を持つことができ、それが車の中にあるかどうかに関係なく、それをいじくり回すことができます。
Nice UMLの例を使用します。
大学に1〜20の異なる学部があり、各学部には1〜5人の教授がいます。大学とその学部の間には構成リンクがあります。部門とその教授の間には集約リンクがあります。
構成は単なる強力な集合体であり、大学が破壊された場合、学部も破壊されるべきです。しかし、たとえそれぞれの学部がなくなっても、教授を殺すべきではありません。
Javaで:
public class University {
private List<Department> departments;
public void destroy(){
//it's composition, when i destroy a university I also destroy the departments. they cant live outside my university instance
if(departments!=null)
for(Department d : departments) d.destroy();
departments.clean();
departments = null;
}
}
public class Department {
private List<Professor> professors;
private University university;
Department(University univ){
this.university = univ;
//check here univ not null throw whatever depending on your needs
}
public void destroy(){
//It's aggregation here, we just tell the professor they are fired but they can still keep living
for(Professor p:professors)
p.fire(this);
professors.clean();
professors = null;
}
}
public class Professor {
private String name;
private List<Department> attachedDepartments;
public void destroy(){
}
public void fire(Department d){
attachedDepartments.remove(d);
}
}
この周りの何か。
簡単な言葉で :
構成と集計の両方が関連付けです。構成->強いHas-A関係集約->弱いHas-A関係。
以下のURLにすばらしい説明があります。
http://www.codeproject.com/Articles/330447/Understanding-Association-Aggregation-and-Composit
チェックしてください!!!
条件を設定しましょう。集約はUML標準のメタタームであり、単純にsharedという名前の構成と共有集約の両方を意味します。しばしば「アグリゲーション」という誤った名前が付けられます。構成も集約なので、それは悪いです。私が理解するように、あなたは「共有」を意味します。
さらにUML標準から:
複合-プロパティが複合的に集約されていることを示します。つまり、複合オブジェクトは、構成されたオブジェクト(パーツ)の存在と保存に責任を持ちます。
だから、大学からカテドラス協会は構成です。なぜならカテドラは大学(IMHO)の外には存在しないからです。
共有集約の正確なセマンティクスは、アプリケーション領域とモデラーによって異なります。
つまり、自分や他の人の原則に従っているだけであれば、他のすべての関連付けは共有の集計として描画できます。 こちら もご覧ください。
簡単な作曲プログラム
public class Person {
private double salary;
private String name;
private Birthday bday;
public Person(int y,int m,int d,String name){
bday=new Birthday(y, m, d);
this.name=name;
}
public double getSalary() {
return salary;
}
public String getName() {
return name;
}
public Birthday getBday() {
return bday;
}
///////////////////////////////inner class///////////////////////
private class Birthday{
int year,month,day;
public Birthday(int y,int m,int d){
year=y;
month=m;
day=d;
}
public String toString(){
return String.format("%s-%s-%s", year,month,day);
}
}
//////////////////////////////////////////////////////////////////
}
public class CompositionTst {
public static void main(String[] args) {
// TODO code application logic here
Person person=new Person(2001, 11, 29, "Thilina");
System.out.println("Name : "+person.getName());
System.out.println("Birthday : "+person.getBday());
//The below object cannot be created. A bithday cannot exixts without a Person
//Birthday bday=new Birthday(1988,11,10);
}
}
最初に、Aggregation
とComposition
の違いが実際に同じページにあることについて話さなければなりません。
集約は、関連付けられたエンティティが関連付けとは無関係に存在できる関連付けです。たとえば、PersonはOrganizationに関連付けられている場合がありますが、Personはシステム内に独立して存在する場合があります。
一方、
構成とは、関連するエンティティの1つが他のエンティティと強く関連しており、他のエンティティが存在しないと存在できない状況を指します。実際、そのエンティティのIDは、常に他のオブジェクトのIDと関連付けられています。たとえば、車の車輪。
次のように、あるエンティティのプロパティを別のエンティティに保持することで、集約を簡単に実現できます。
class Person {
Organisation worksFor;
}
class Organisation {
String name;
}
class Main {
public static void main(String args[]) {
//Create Person object independently
Person p = new Person();
//Create the Organisation independently
Organisation o = new Organisation();
o.name = "XYZ Corporation";
/*
At this point both person and organisation
exist without any association
*/
p.worksFor = o;
}
}
コンポジションの場合、依存オブジェクトは、常に関連オブジェクトのIDで作成される必要があります。同じために内部クラスを使用できます。
class Car {
class Wheel {
Car associatedWith;
}
}
class Main {
public static void main() {
//Create Car object independently
Car car = new Car();
//Cannot create Wheel instance independently
//need a reference of a Car for the same.
Car.Wheel wheel = car.new Wheel();
}
}
同じユースケースは、アプリケーションシナリオによっては集約/構成に該当する場合があることに注意してください。たとえば、ある組織で働く人々のためのアプリケーションを開発している場合、組織への参照がサインアップのために必要である場合、Person-Organisationケースは構成になる場合があります。同様に、車の部品の在庫を維持している場合、車と車輪の関係を集約できます。
どちらのタイプももちろん関連付けであり、実際にそのような言語要素に厳密にマッピングされるわけではありません。違いは、目的、コンテキスト、およびシステムのモデル化方法にあります。
実際の例として、2つの異なるタイプのシステムを同様のエンティティと比較します。
自動車登録システム。主に自動車とその所有者などを追跡します。ここでは、エンジンを別のエンティティとしては興味がありませんが、パワーや燃料の種類など、エンジン関連の属性がまだある場合があります。ここで、エンジンはcomposite自動車エンティティの一部である可能性があります。
車の部品を管理し、車にサービスを提供し、部品を交換し、場合によっては完全なエンジンを使用するカーサービスショップ管理システム。ここでは、エンジンを在庫している可能性があり、それらと他の部品を車とは別に個別に追跡する必要があります。ここで、エンジンは集約自動車エンティティの一部である場合があります。
あなたの言語でこれをどのように実装するかは、そのレベルでは読みやすさのようなものがはるかに重要であるため、さほど重要ではありません。