ความแตกต่างของการนำไปใช้งานระหว่าง Aggregation และ Composition ใน Java


103

ฉันตระหนักถึงความแตกต่างของแนวคิดระหว่างการรวมและองค์ประกอบ ใครช่วยบอกฉันถึงความแตกต่างของการใช้งานใน Java ระหว่างพวกเขาพร้อมตัวอย่างได้ไหม


3
ไปที่ลิงก์นี้คุณอาจได้รับคำตอบสำหรับโพสต์ของคุณ [ความแตกต่างระหว่างการรวมและการ
เรียบเรียง

ความเป็นไปได้ที่จะทำซ้ำของAggregation เทียบกับ Composition
Alex K


เมื่อเรามีความสัมพันธ์ระหว่างวัตถุสิ่งนั้นเรียกว่า Association การรวมและองค์ประกอบทั้งสองเป็นรูปแบบเฉพาะของสมาคม องค์ประกอบเป็นรูปแบบ Aggregation ที่เชี่ยวชาญอีกครั้ง javabench.in/2011/08/difference-between-association.html
Raúl

คุณสามารถหาคำตอบเพิ่มเติมได้ที่นี่
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();
  }
}

ในกรณีขององค์ประกอบเครื่องยนต์ถูกห่อหุ้มโดยรถยนต์อย่างสมบูรณ์ ไม่มีทางที่โลกภายนอกจะได้รับการอ้างอิงถึง Engine เครื่องยนต์มีชีวิตและตายไปพร้อมกับรถ ด้วยการรวมตัวรถยังทำหน้าที่ของมันผ่านเครื่องยนต์ แต่เครื่องยนต์ไม่ได้เป็นส่วนภายในของรถเสมอไป อาจมีการสลับเครื่องยนต์หรือแม้แต่ถอดออกทั้งหมด ไม่เพียงแค่นั้น แต่โลกภายนอกยังสามารถอ้างอิงถึงเครื่องยนต์และคนจรจัดด้วยไม่ว่าจะอยู่ในรถก็ตาม


7
ตัวอย่างยอดเยี่ยม! นอกจากนี้ยังแสดงให้เห็นถึงองค์ประกอบที่มีการเชื่อมโยงที่แข็งแกร่ง (รถยนต์ไม่สมเหตุสมผลหากไม่มีเครื่องยนต์) และการรวมตัวเป็นการเชื่อมโยงที่อ่อนแอ (รถยนต์ที่ไม่มีเครื่องยนต์มีความหมายโดยสิ้นเชิงไม่จำเป็นต้องมีหนึ่งในตัวสร้าง) จะใช้ตัวไหนดี? ขึ้นอยู่กับบริบท
Federico Pugnali

@ และตัวอย่างที่คุณให้ใน Aggregation ไม่ใช่ตัวอย่างการพึ่งพาหรือไม่? การพึ่งพาเป็นรูปแบบความสัมพันธ์ที่อ่อนแอกว่าและในเงื่อนไขรหัสบ่งชี้ว่าคลาสใช้พารามิเตอร์อื่นหรือประเภทการส่งคืน
OOkhan

@Anand: คุณช่วยอธิบายเพิ่มเติมได้ไหมว่าทำไมคุณถึงพูด: ในกรณีของการจัดองค์ประกอบไม่มีทางที่โลกภายนอกจะได้รับการอ้างอิงถึง Engine โดยการรวมโลกภายนอกสามารถอ้างอิงถึง Engine ได้ คุณสามารถแสดงในตัวอย่างโค้ดได้หรือไม่ว่าโลกภายนอกสามารถหรือไม่สามารถอ้างอิงถึงเครื่องยนต์ได้อย่างไร ขอบคุณ
O Connor

9
นี่ไม่ใช่ตัวอย่างที่ถูกต้อง โลกภายนอกสามารถเข้าถึงวัตถุภายในได้ แต่ตัวตนของมันจะเชื่อมโยงกับวัตถุภายนอกเสมอในขณะที่การรวมวัตถุภายในอาจมีอยู่อย่างอิสระแม้ว่าจะไม่มีรถยนต์ก็ตาม ในกรณีนี้ยังคงสามารถสร้างเครื่องยนต์ได้โดยใช้การnew Engine(EngineSpecs)โทรแม้ว่าจะไม่มีรถก็ตาม วิธีที่จะทำให้ได้องค์ประกอบคือการสร้าง Engine เป็นคลาสภายในเพื่อให้วัตถุของเครื่องยนต์ถูกสร้างขึ้นโดยอ้างอิงถึง Car Object
เสมอ

@mickeymoon ที่ดีจับ. คุณช่วยชี้ให้เราเห็นตัวอย่างที่ดีกว่านี้ได้ไหม
Gayan Weerakutti

20

ฉันจะใช้ตัวอย่าง 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);
     }
}

บางสิ่งบางอย่างรอบ ๆ นี้

แก้ไข: ตัวอย่างตามที่ร้องขอ

public class Test
{
    public static void main(String[] args)
    {
        University university = new University();
        //the department only exists in the university
        Department dep = university.createDepartment();
        // the professor exists outside the university
        Professor prof = new Professor("Raoul");
        System.out.println(university.toString());
        System.out.println(prof.toString());

        dep.assign(prof);
        System.out.println(university.toString());
        System.out.println(prof.toString());
        dep.destroy();

        System.out.println(university.toString());
        System.out.println(prof.toString());

    }


}

ชั้นเรียนมหาวิทยาลัย

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class University {

    private List<Department> departments = new ArrayList<>();

    public Department createDepartment() {
        final Department dep = new Department(this, "Math");
        departments.add(dep);
        return dep;
    }

    public void destroy() {
        System.out.println("Destroying university");
        //it's composition, when I destroy a university I also destroy the departments. they cant live outside my university instance
        if (departments != null)
            departments.forEach(Department::destroy);
        departments = null;
    }

    @Override
    public String toString() {
        return "University{\n" +
                "departments=\n" + departments.stream().map(Department::toString).collect(Collectors.joining("\n")) +
                "\n}";
    }
}

ชั้นเรียน

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Department {

    private final String name;
    private List<Professor> professors = new ArrayList<>();
    private final University university;

    public Department(University univ, String name) {
        this.university = univ;
        this.name = name;
        //check here univ not null throw whatever depending on your needs
    }

    public void assign(Professor p) {
        //maybe use a Set here
        System.out.println("Department hiring " + p.getName());
        professors.add(p);
        p.join(this);
    }

    public void fire(Professor p) {
        //maybe use a Set here
        System.out.println("Department firing " + p.getName());
        professors.remove(p);
        p.quit(this);
    }

    public void destroy() {
        //It's aggregation here, we just tell the professor they are fired but they can still keep living
        System.out.println("Destroying department");
        professors.forEach(professor -> professor.quit(this));
        professors = null;
    }

    @Override
    public String toString() {
        return professors == null
                ? "Department " + name + " doesn't exists anymore"
                : "Department " + name + "{\n" +
                "professors=" + professors.stream().map(Professor::toString).collect(Collectors.joining("\n")) +
                "\n}";
    }
}

ชั้นศาสตราจารย์

import java.util.ArrayList;
import java.util.List;

public class Professor {

    private final String name;
    private final List<Department> attachedDepartments = new ArrayList<>();

    public Professor(String name) {
        this.name = name;
    }

    public void destroy() {

    }

    public void join(Department d) {
        attachedDepartments.add(d);
    }

    public void quit(Department d) {
        attachedDepartments.remove(d);
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Professor " + name + " working for " + attachedDepartments.size() + " department(s)\n";
    }
}

การนำไปใช้นั้นเป็นที่ถกเถียงกันเนื่องจากขึ้นอยู่กับวิธีที่คุณต้องการจัดการการสร้างการจ้างการลบ ฯลฯ ไม่เกี่ยวข้องกับ OP


ฉันหวังว่าฉันจะไม่ได้รับความคิดเห็นใด ๆ เกี่ยวกับรายการที่ไม่ได้เริ่มต้นและไม่มีตัวสร้าง ฉันเขียนสิ่งนี้อย่างรวดเร็วส่วนที่ขาดหายไปเป็นเรื่องธรรมดา แต่ถ้าถูกถามฉันจะแก้ปัญหาให้เสร็จ
TecHunter

ขอบคุณ! ตัวอย่างของคุณชัดเจนมาก แต่ฉันไม่เข้าใจภาพประกอบรหัสของคุณ คุณช่วยบอกความแตกต่างในการใช้งานพื้นฐานระหว่างทั้งสองได้ไหม ถ้าฉันต้องใช้ Aggregation หรือองค์ประกอบฉันควรใช้แนวคิดอะไรใน Java
Rajath

มันเป็นการใช้งานที่เหมือนกันทุก
ประการ

TecHunter ฉันกำลังมองหาตัวอย่างนี้ คุณสามารถขยายรหัส java เพื่อสาธิตการเชื่อมโยงในตัวอย่างมหาวิทยาลัยได้หรือไม่ ตัวอย่างควรทำงานอย่างไรในเมธอด main () (ซึ่งอาจแสดงสถานการณ์ของการสร้างมหาวิทยาลัยและการลบอาจารย์) โปรดช่วย
deepakl.2000

@ deepakl.2000 หลายวิธีในการทำเช่นนี้ คุณควรกำหนดว่าคลาสใดมีอำนาจ อาจเป็นศาสตราจารย์ที่เข้าร่วมมหาวิทยาลัยหนึ่งต่อหลายแผนกหรืออาจเป็นมหาวิทยาลัยที่จ้างศาสตราจารย์แล้วขอให้ภาควิชาลงทะเบียน ทั้งหมดนี้เกี่ยวกับสิ่งที่เหมาะสมกับความต้องการของคุณมากกว่า
TecHunter

4

มีคำอธิบายที่ดีใน url ที่ระบุด้านล่าง

ป้อนคำอธิบายภาพที่นี่

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

โปรดตรวจสอบ!!!


สวัสดี Rahul แม้ว่าลิงก์นี้อาจตอบคำถามได้ แต่ควรรวมส่วนสำคัญของคำตอบไว้ที่นี่และระบุลิงก์เพื่อการอ้างอิง คำตอบแบบลิงก์เท่านั้นอาจไม่ถูกต้องหากหน้าที่เชื่อมโยงเปลี่ยนไป โปรดดูที่นี่: ทำไมและอย่างไรคำตอบบางคำจึงถูกลบ
bummi

3

โปรแกรมจัดองค์ประกอบแบบง่ายๆ

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

    }
}

คุณสามารถเพิ่มรหัสจาวาที่ใช้งานได้สำหรับการเชื่อมโยงและการรวมรวมทั้งอธิบายสถานการณ์ทั้งหมดตามที่คุณอธิบายไว้ในองค์ประกอบได้หรือไม่ 1. สถานการณ์ในการเชื่อมโยงถ้าพวกเขาถูกลบ? 2. สถานการณ์ใน Aggregation เมื่ออ็อบเจ็กต์พาเรนต์ถูกลบ?
deepakl.2000

3

ความแตกต่างคือองค์ประกอบใด ๆ เป็นการรวมและไม่ใช่ในทางกลับกัน

มาตั้งเงื่อนไขกัน การรวมเป็น metaterm ในมาตรฐาน UML และวิธีการทั้งสององค์ประกอบและการรวมตัวร่วมกันเพียงชื่อที่ใช้ร่วมกัน บ่อยครั้งที่มีการตั้งชื่อ "การรวม" อย่างไม่ถูกต้อง มันไม่ดีสำหรับการจัดองค์ประกอบก็คือการรวมตัวเช่นกัน ตามที่ฉันเข้าใจคุณหมายถึง "แชร์"

เพิ่มเติมจากมาตรฐาน UML:

คอมโพสิต - ระบุว่าคุณสมบัติถูกรวมแบบผสมกล่าวคือออบเจ็กต์ผสมมีความรับผิดชอบต่อการมีอยู่และการจัดเก็บของวัตถุที่ประกอบขึ้น (ชิ้นส่วน)

ดังนั้นความสัมพันธ์ระหว่างมหาวิทยาลัยกับวิหารจึงเป็นองค์ประกอบเนื่องจากมหาวิหารไม่มีอยู่นอกมหาวิทยาลัย (IMHO)

ความหมายที่แม่นยำของการรวมแบบแบ่งใช้จะแตกต่างกันไปตามพื้นที่แอปพลิเคชันและตัวสร้างแบบจำลอง

กล่าวคือความสัมพันธ์อื่น ๆ ทั้งหมดสามารถวาดเป็นการรวมที่ใช้ร่วมกันได้หากคุณปฏิบัติตามหลักการบางอย่างของคุณหรือของคนอื่นเท่านั้น ดูที่นี่ด้วย


3

พูดง่ายๆคือ

ทั้งองค์ประกอบและการรวมเป็นสมาคม องค์ประกอบ -> การรวมความสัมพันธ์ที่แข็งแกร่ง -> ความสัมพันธ์ที่อ่อนแอของ Has-A


2

ก่อนอื่นเราต้องพูดถึงความแตกต่างระหว่างAggregationและCompositionที่จะอยู่ในหน้าเดียวกัน

การรวมคือการเชื่อมโยงที่อาจมีนิติบุคคลที่เกี่ยวข้องโดยไม่ขึ้นอยู่กับการเชื่อมโยง ตัวอย่างเช่นบุคคลอาจมีความเกี่ยวข้องกับองค์กร แต่เขา / เธออาจมีการดำรงอยู่อย่างอิสระในระบบ

ในขณะที่

องค์ประกอบหมายถึงสถานการณ์ที่หนึ่งในเอนทิตีที่เกี่ยวข้องมีความสัมพันธ์อย่างมากกับอีกเอนทิตีและไม่สามารถดำรงอยู่ได้หากปราศจากการดำรงอยู่ของอีกฝ่าย ในความเป็นจริงข้อมูลประจำตัวของเอนทิตีนั้นจะเชื่อมโยงกับข้อมูลประจำตัวของวัตถุอื่นเสมอ ตัวอย่างเช่นล้อในรถยนต์

ตอนนี้การรวมสามารถทำได้โดยการถือคุณสมบัติของเอนทิตีหนึ่งในอีกเอนทิตีดังนี้:

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;

    }
}

สำหรับการจัดองค์ประกอบนั้นจำเป็นที่จะต้องสร้างอ็อบเจกต์ที่เชื่อมโยงกับข้อมูลประจำตัวของวัตถุที่เกี่ยวข้องเสมอ คุณสามารถใช้คลาสชั้นในได้

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

โปรดทราบว่ากรณีการใช้งานเดียวกันอาจอยู่ภายใต้การรวม / องค์ประกอบขึ้นอยู่กับสถานการณ์การใช้งาน ตัวอย่างเช่นกรณีบุคคล - องค์กรอาจกลายเป็นองค์ประกอบหากคุณกำลังพัฒนาแอปพลิเคชันสำหรับบุคคลที่ทำงานในบางองค์กรและต้องมีการอ้างอิงถึงองค์กรเพื่อลงชื่อสมัครใช้ ในทำนองเดียวกันหากคุณกำลังดูแลสินค้าคงคลังสำหรับชิ้นส่วนของรถยนต์ความสัมพันธ์ของล้อรถสามารถรวมกันได้


1

การรวมเทียบกับองค์ประกอบ

การรวมหมายถึงความสัมพันธ์ที่เด็กสามารถดำรงอยู่ได้โดยไม่ขึ้นกับผู้ปกครอง ตัวอย่างเช่นธนาคารและพนักงานลบธนาคารและพนักงานยังคงอยู่

ในขณะที่องค์ประกอบหมายถึงความสัมพันธ์ที่เด็กไม่สามารถดำรงอยู่ได้กับผู้ปกครอง ตัวอย่าง: มนุษย์และหัวใจหัวใจไม่ได้แยกจากมนุษย์

ความสัมพันธ์การรวมคือ“ has-a”และองค์ประกอบคือความสัมพันธ์“ part-of”

องค์ประกอบเป็นสมาคมที่แข็งแกร่งในขณะที่การรวมตัวเป็นสมาคมที่อ่อนแอ


0

ทั้งสองประเภทเป็นการเชื่อมโยงกันแน่นอนและไม่ได้แมปอย่างเคร่งครัดกับองค์ประกอบของภาษาเช่นนั้น ความแตกต่างอยู่ที่วัตถุประสงค์บริบทและวิธีการจำลองระบบ

เป็นตัวอย่างที่ใช้ได้จริงเปรียบเทียบระบบสองประเภทที่มีเอนทิตีที่คล้ายคลึงกัน

  • ระบบการลงทะเบียนรถยนต์ที่ติดตามรถยนต์เป็นหลักและเจ้าของเป็นต้นที่นี่เราไม่ได้สนใจว่าเครื่องยนต์เป็นหน่วยงานแยกต่างหาก แต่เราอาจยังมีคุณลักษณะที่เกี่ยวข้องกับเครื่องยนต์เช่นกำลังและประเภทของเชื้อเพลิง ในที่นี้เครื่องยนต์อาจเป็นส่วนประกอบของรถยนต์

  • ระบบการจัดการร้านบริการรถยนต์ที่จัดการชิ้นส่วนรถยนต์ซ่อมบำรุงรถยนต์และเปลี่ยนชิ้นส่วนเครื่องยนต์อาจจะสมบูรณ์ ที่นี่เราอาจมีเครื่องยนต์ในสต็อกและจำเป็นต้องติดตามพวกมันและชิ้นส่วนอื่น ๆ แยกจากกันและไม่ขึ้นกับรถยนต์ ที่นี่เครื่องยนต์อาจเป็นส่วนรวมของรถยนต์

วิธีที่คุณใช้สิ่งนี้ในภาษาของคุณเป็นเรื่องที่น่ากังวลเล็กน้อยเนื่องจากในระดับนั้นสิ่งต่างๆเช่นความสามารถในการอ่านนั้นสำคัญกว่ามาก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.