Javaでの集約と構成の実装の違い


102

アグリゲーションとコンポジションの概念的な違いを知っています。誰かがJavaの実装の違いを例を挙げて教えてもらえますか?


3
このリンクをたどると、投稿への回答が得られます[集約と構成の違い] [1] [1]:stackoverflow.com/a/1468285/1353243
gks



オブジェクト間に何らかの関係がある場合、それは関連と呼ばれます。アグリゲーションとコンポジションはどちらもアソシエーションの特殊な形式です。合成もまた、特殊化された集約形式です。 javabench.in/2011/08/difference-between-association.html
ラウル

あなたはここで
hamed moosaei

回答:


222

組成

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

構成の場合、エンジンは車によって完全にカプセル化されます。外部の世界がエンジンへの参照を取得する方法はありません。エンジンは車と共に生き、そして死ぬ。アグリゲーションでは、車もエンジンを介してその機能を実行しますが、エンジンは常に車の内部部品であるとは限りません。エンジンは交換されるか、完全に削除されることもあります。それだけでなく、外の世界でもエンジンへの参照を保持でき、車内にあるかどうかに関係なくそれをいじくります。


7
素晴らしい例!また、強い関連性(CarはEngineなしでは意味がありません)としての構成と、弱い関連性(EngineなしのCarは完全に意味があるため、コンストラクターで1つも必要ない)としての集約を示しています。どちらを使用しますか?コンテキストによって異なります。
フェデリコプニャーリ2012年

@Anand集計でuが与える例は、この依存関係の例ではありませんか?依存関係は関係の弱い形式であり、コード用語では、クラスがパラメーターまたは戻り値の型によって別のクラスを使用することを示します。
OOkhan 2013年

@アナンド:あなたが言った理由をもっと説明できますか:合成の場合、外界がエンジンへの参照を取得する方法はなく、集計では外界がエンジンへの参照を持つことができますか?コードのサンプルで、外の世界がどのようにエンジンへの参照を持つことができるかできないかを示すことができますか?ありがとう
O Connor

9
これは正しい例ではありません。外の世界は内部のオブジェクトにアクセスできますが、IDは常に外部のオブジェクトに関連付けられていますが、集合体では、車がなくても内部のオブジェクトが独立して存在する可能性があります。この場合、new Engine(EngineSpecs)車がなくても、呼び出しを使用してエンジンを作成できます。構成を実現する方法は、エンジンを内部クラスとして作成することです。これにより、エンジンのオブジェクトは常にCarオブジェクトを参照して作成されます
mickeymoon

@mickeymoon素晴らしいキャッチ。より良い例を教えていただけますか?
Gayan Weerakutti

19

すばらしい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);
     }
}

これの周りの何か。


初期化されていないリストやコンストラクタがないことについてはコメントをいただけないでしょうか。私はこれをすばやく書きましたが、足りない部分は常識ですが、質問があれば解決します
TecHunter

ありがとう!あなたの例は完全に明確です。しかし、私はあなたのコードのイラストを理解できませんでした。2つの基本的な実装の違いを教えていただけますか?集約または合成を実装する必要がある場合、Javaのどの概念を使用する必要がありますか?
Rajath 2012

クラスについて話す場合はまったく同じ実装ですが、私の構成のようにインスタンスを管理する方法によって構成が反映されるべきです
TecHunter

4

以下のURLに説明があります。

ここに画像の説明を入力してください

http://www.codeproject.com/Articles/330447/Understanding-Association-Aggregation-and-Composit

チェックしてください!!!


こんにちはRahulです。このリンクで質問に答えることができますが、回答の重要な部分をここに含め、参照用のリンクを提供することをお勧めします。リンクされたページが変更されると、リンクのみの回答が無効になる可能性があります。こちらをご覧ください:なぜ、どのようにしていくつかの回答が削除されますか?
bummi

3

違いは、どの構成も集約であり、その逆ではないことです。

条件を設定しましょう。集約はUML標準のメタタームであり、単にsharedという名前の構成と共有集約の両方を意味ます。多くの場合、誤って「集計」と呼ばれます。構成も集合体なので悪いです。私が理解しているように、あなたは「共有」を意味します。

UML標準からさらに:

composite-プロパティが複合的に集約されていることを示します。つまり、複合オブジェクトは、構成されたオブジェクト(パーツ)の存在と格納に責任を持ちます。

したがって、大学とカテドラルの関連付けは構成です。なぜなら、カテドラルは大学の外に存在しないからです(IMHO)

共有集約の正確なセマンティクスは、アプリケーション領域とモデラーによって異なります。

つまり、自分または他の誰かのいくつかの原則に従っているだけの場合は、他のすべての関連付けを共有集約として描画できます。また、見てここに


3

簡単な言葉で :

構成と集約の両方が関連付けです。構成->強いHas-A関係集約->弱いHas-A関係。


2

シンプルな作曲プログラム

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

    }
}

2

まず、違い、実際に何について話しなければならないAggregationとは、Composition同じページになることです。

集約は、関連付けられたエンティティが関連付けから独立して存在する可能性がある関連付けです。たとえば、個人は組織に関連付けられている場合がありますが、システム内に独立して存在している場合があります。

一方

構成とは、関連するエンティティの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-Organizationケースは構成になる可能性があります。同様に、車の部品の在庫を維持している場合、車と車輪の関係を集約することができます。


1

集計と構成

集約は、子が親から独立して存在できる関係を意味します。たとえば、銀行と従業員は銀行を削除し、従業員はまだ存在しています。

一方、コンポジションは、子供が親から独立して存在できない関係を意味します。例:人間と心臓、心臓は人間とは別に存在しません。

集約関係は「has-a」であり、構成は「part-of」関係です。

構成は強い関連ですが、集約は弱い関連です。


0

どちらのタイプももちろん関連付けであり、実際にはそのような言語要素に厳密にマッピングされていません。違いは、目的、コンテキスト、およびシステムのモデル化方法です。

実際の例として、2つの異なるタイプのシステムを類似のエンティティーと比較します。

  • 主に自動車やその所有者などを追跡する自動車登録システム。ここでは、独立したエンティティとしてのエンジンには関心がありませんが、出力や燃料のタイプなど、エンジンに関連する属性がまだある場合があります。ここで、エンジンは自動車エンティティの複合部品である場合があります。

  • 自動車部品を管理し、車の整備を行い、部品を交換する、おそらく完全なエンジンである自動車サービスショップ管理システム。ここでは、エンジンをストックしていて、それらと他のパーツを別々に、車から独立して追跡する必要があるかもしれません。ここで、エンジンは自動車エンティティの集約された部分である場合があります。

このレベルでは可読性などがはるかに重要になるため、これを言語に実装する方法はそれほど重要ではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.