Sự khác biệt giữa hiệp hội, tập hợp và thành phần là gì?


389

Sự khác biệt giữa hiệp hội, tập hợp và thành phần là gì? Hãy giải thích về mặt thực hiện.


2
Đây có thể là một chút áp đảo cho người mới bắt đầu, nhưng đi dạo wee qua UML 2 Superstructure spec: omg.org/docs/formal/09-02-02.pdf Mục 7.3.3 cho Hiệp hội
chickeninabiscuit

6
Tôi cũng nên thêm vào, trong UML 2 không có Phần tử nào như Tập hợp hoặc Thành phần (mặc dù trong UML 1.4). Trong UML 2, tập hợp / thành phần được triển khai dưới dạng các thành phần Hiệp hội với thuộc tính AggregationKind được đặt thành Chia sẻ hoặc Kết hợp.
bánh quy gà

Đã có rất nhiều câu trả lời trên SO: stackoverflow.com/search?q=aggregation+and+compocation
lothar

2
bài viết hữu ích ở đây codeproject.com/Articles/22769/ Lời
GibboK

6
Tôi biết điều này đã được trả lời nhiều lần, nhưng tôi cảm thấy lời giải thích tốt nhất mà tôi từng đọc về vấn đề này là: holub.com/goodies/uml/#compocation
WLin

Câu trả lời:


385

Đối với hai đối tượng FooBarcác mối quan hệ có thể được xác định

Hiệp hội - Tôi có một mối quan hệ với một đối tượng. Foosử dụngBar

public class Foo { 
    void Baz(Bar bar) {
    } 
};

Thành phần - Tôi sở hữu một đối tượng và tôi chịu trách nhiệm cho cuộc đời của nó. Khi Foochết, cũng vậyBar

public class Foo {
    private Bar bar = new Bar(); 
}

Tập hợp - Tôi có một đối tượng mà tôi đã mượn từ người khác. Khi Foochết, Barcó thể sống.

public class Foo { 
    private Bar bar; 
    Foo(Bar bar) { 
       this.bar = bar; 
    }
}

3
Có vẻ như mã C # / Java. Nếu đó là trường hợp, cả mã Hiệp hội và Mã tổng hợp đều giống nhau. Trong cả hai trường hợp, 'thanh' chỉ được tham chiếu và Barđối tượng có thể sống.
Ajay

@Jeff Foster: Tôi có một số nghi ngờ. Nếu tôi khởi tạo đối tượng thanh trong Baz (Bar bar) {bar = new Bar (); } trong trường hợp đầu tiên. Nó sẽ vẫn là hiệp hội hay nó sẽ trở thành sáng tác bây giờ?
Saket

21
@Ajay: Tập hợp giữ tham chiếu của các đối tượng không phải là trường hợp liên kết. Do đó sự khác biệt của việc thực hiện.
ABCD

17
Hiệp hội mạnh hơn một chút so với chỉ sử dụng như một tham số phương thức. Tôi tin rằng đoạn mã liên kết của bạn tương ứng nhiều hơn với mối quan hệ Phụ thuộc . bạn có thể muốn kiểm tra bài viết liên quan đến Martin Fowler
Ahmad Abdelghany

5
@AhmadAbdelghany là chính xác. Ví dụ đầu tiên là một mối quan hệ phụ thuộc. Cái thứ ba hoạt động cho sự liên kết và tổng hợp.
André Valenti

122

Tôi biết câu hỏi này được gắn thẻ là C # nhưng các khái niệm là những câu hỏi khá chung chung như chuyển hướng này ở đây. Vì vậy, tôi sẽ cung cấp quan điểm của tôi ở đây (một chút sai lệch so với quan điểm java nơi tôi thấy thoải mái hơn).

Khi chúng ta nghĩ về bản chất hướng đối tượng, chúng ta luôn nghĩ về Đối tượng, lớp (bản thiết kế đối tượng) và mối quan hệ giữa chúng. Các đối tượng có liên quan và tương tác với nhau thông qua các phương thức. Nói cách khác, đối tượng của một lớp có thể sử dụng các dịch vụ / phương thức được cung cấp bởi đối tượng của lớp khác. Loại mối quan hệ này được gọi là hiệp hội. .

Tập hợp và thành phần là tập hợp con của hiệp hội có nghĩa là chúng là trường hợp cụ thể của liên kết.

nhập mô tả hình ảnh ở đây

  • Trong cả hai đối tượng tổng hợp và thành phần của một đối tượng "sở hữu" của một lớp khác .
  • Nhưng có một sự khác biệt tinh tế. Trong Thành phần , đối tượng của lớp được sở hữu bởi đối tượng của lớp sở hữu nó không thể tự sống (Còn được gọi là "mối quan hệ chết chóc"). Nó sẽ luôn sống như một phần của đối tượng sở hữu của nó trong đó trong Tập hợp , đối tượng phụ thuộc là độc lập và có thể tồn tại ngay cả khi đối tượng sở hữu lớp đã chết.
  • Vì vậy, trong thành phần nếu sở hữu đối tượng là rác được thu thập, đối tượng sở hữu cũng sẽ không phải là trường hợp tổng hợp.

Bối rối?

Ví dụ về thành phần : Xem xét ví dụ về Xe hơi và động cơ rất đặc trưng cho xe đó (có nghĩa là nó không thể được sử dụng trong bất kỳ chiếc xe nào khác). Loại mối quan hệ giữa Xe lớp Lớp cụ thể được gọi là Thành phần. Một đối tượng của lớp Xe không thể tồn tại mà không có đối tượng của lớp Cụ thể và đối tượng của Cụ thể không có ý nghĩa nếu không có Lớp Xe. Nói một cách đơn giản, lớp Xe chỉ "sở hữu" lớp Cụ thể.

Ví dụ tổng hợp : Bây giờ hãy xem xét lớp XeBánh xe lớp . Xe cần một đối tượng Bánh xe để hoạt động. Có nghĩa là đối tượng Xe sở hữu đối tượng Bánh xe nhưng chúng ta không thể nói đối tượng Bánh xe không có ý nghĩa gì nếu không có Đối tượng Xe hơi. Nó rất có thể được sử dụng trong Xe đạp, Xe tải hoặc Xe ô tô khác nhau.

Tổng kết nó -

Tóm lại, hiệp hội là một thuật ngữ rất chung được sử dụng để thể hiện khi một lớp sử dụng các chức năng được cung cấp bởi một lớp khác. Chúng ta nói nó là thành phần nếu một đối tượng lớp cha sở hữu một đối tượng lớp con khác và đối tượng lớp con đó không thể tồn tại một cách có ý nghĩa nếu không có đối tượng lớp cha. Nếu nó có thể thì nó được gọi là Uẩn.

Thêm chi tiết tại đây. Tôi là tác giả của http://opensourceforgeek.blogspot.in và đã thêm một liên kết ở trên vào bài đăng có liên quan để có thêm ngữ cảnh.


8
Tôi sẽ hỏi tại sao bạn quan tâm để trả lời một câu hỏi đã được trả lời đã được hỏi hơn 5 năm trước nhưng sau đó tôi đọc mục blog của bạn và nó có nhiều thông tin hơn một số câu trả lời ở đây. Nâng cao!
Donbhupi

2
Tôi đồng ý với @Donbhupi câu trả lời của bạn có nhiều thông tin và chính xác hơn nhiều người khác
zish

1
Thật là buồn cười khi các nhà phát triển C # và Java tuyên bố họ sử dụng thành phần khi nó chỉ tồn tại trên các kiểu nguyên thủy với các ngôn ngữ đó. Nếu bạn muốn thực sự hiểu về bố cục, bạn phải sử dụng C ++, trong đó các đối tượng có thể THỰC SỰ là một phần của các đối tượng khác .. Không chỉ trôi nổi trong bộ nhớ heap và giữ các con trỏ với nhau và tuyên bố có thành phần ..
Mọi người vào

@Everyone tôi đã đi đến kết luận giống như bạn, nhưng tôi không chắc về điều đó. Ví dụ: giả sử tôi có một lớp thuộc sở hữu ngữ nghĩa của một lớp cụ thể, tuy nhiên đối tượng sở hữu là rác được thu thập sau khi chủ sở hữu của nó đã bị người thu gom rác xóa, nó có được coi là một thành phần không?
Paulo André Haacke

Chúng ta có thể có thành phần trong mã ac # bằng bộ nhớ được quản lý không?
Paulo André Haacke

85

Hội là khái niệm khái quát về quan hệ. Nó bao gồm cả Thành phần và Tập hợp.

Thành phần ( hỗn hợp ) là một cách để bọc các đối tượng hoặc kiểu dữ liệu đơn giản thành một đơn vị . Các tác phẩm là một khối xây dựng quan trọng của nhiều cấu trúc dữ liệu cơ bản

Tập hợp ( bộ sưu tập ) khác với thành phần thông thường ở chỗ nó không bao hàm quyền sở hữu. Trong thành phần, khi đối tượng sở hữu bị phá hủy, các đối tượng được chứa cũng vậy. Tóm lại, điều này không nhất thiết đúng.

Cả hai đều biểu thị mối quan hệ giữa các đối tượng và chỉ khác nhau về sức mạnh của họ.

Thủ thuật để nhớ sự khác biệt: có A - Một tập hợp và O wn - c O mposeitoin

nhập mô tả hình ảnh ở đây

Bây giờ hãy quan sát hình ảnh sau đây

quan hệ

nhập mô tả hình ảnh ở đây

Sự giống nhau:

Bố cục : Hình ảnh sau đây là bố cục hình ảnh tức là sử dụng từng hình ảnh tạo thành một hình ảnh.
nhập mô tả hình ảnh ở đây

Tập hợp : tập hợp hình ảnh ở một vị trí

nhập mô tả hình ảnh ở đây

Ví dụ, Một trường đại học sở hữu nhiều phòng ban khác nhau và mỗi khoa có một số giáo sư. Nếu trường đại học đóng cửa, các khoa sẽ không còn tồn tại, nhưng các giáo sư trong các khoa đó sẽ tiếp tục tồn tại. Do đó, một trường đại học có thể được coi là một thành phần của các khoa, trong khi các khoa có một tập hợp các giáo sư. Ngoài ra, một giáo sư có thể làm việc ở nhiều bộ phận, nhưng một bộ phận không thể là một phần của nhiều trường đại học.


14
Sau khi đọc rất nhiều về chủ đề này, câu trả lời này là câu hỏi dễ hiểu nhất. Nên được đưa lên wikipedia.
Jankapunkt

1
Đẹp khớp nối.
Sid

Liên quan đến tổng hợp, bạn nói "Đối tượng con thuộc về một phụ huynh". Điều này LAF không đúng. Đó là UML hợp lệ để có tổng hợp chung, tức là một đứa trẻ thuộc về nhiều cha mẹ. Bạn thừa nhận điều này trong ví dụ của bạn về Bộ như một tập hợp các Giáo sư, bởi vì bạn nói rằng một Giáo sư có thể làm việc cho nhiều Bộ.
www.admiraalit.nl

@ www.admiraalit.nl AFAIK chia sẻ tổng hợp không có nghĩa là "một đứa trẻ thuộc về nhiều cha mẹ", nó chỉ là cách khác, nhiều đứa trẻ thuộc về cùng một cha mẹ. Và đó là một tập hợp không tổng hợp bởi vì ngay cả khi cha mẹ chết, con cái vẫn có thể tồn tại lâu hơn.
aderchox

65

Phụ thuộc (tài liệu tham khảo)
Có nghĩa là không có liên kết khái niệm giữa hai đối tượng. ví dụ tham chiếu đối tượng EnrollmentService đối tượng Sinh viên & Khóa học (dưới dạng tham số phương thức hoặc kiểu trả về)

public class EnrollmentService {
    public void enroll(Student s, Course c){}
}

Hiệp hội (has-a)
Có nghĩa là hầu như luôn có một liên kết giữa các đối tượng (chúng được liên kết). Đối tượng đặt hàng có một đối tượng Khách hàng

public class Order {
    private Customer customer
}

Tập hợp (có-a + toàn bộ)
Loại liên kết đặc biệt trong đó có mối quan hệ toàn bộ giữa hai đối tượng. họ có thể sống mà không có nhau

public class PlayList{
    private List<Song> songs;
}

Lưu ý: phần khó nhất là phân biệt tập hợp với liên kết thông thường. Thành thật mà nói, tôi nghĩ rằng điều này là mở cho các cách hiểu khác nhau.

Thành phần (có-a + toàn bộ phần + quyền sở hữu)
Loại tổng hợp đặc biệt. An Apartmentgồm một số Rooms. A Roomkhông thể tồn tại mà không có Apartment. khi một căn hộ bị xóa, tất cả các phòng liên quan cũng bị xóa.

public class Apartment{
    private Room bedroom;
    public Apartment() {
       bedroom = new Room();
    }
}

1
Yup, phần khó khăn duy nhất trong việc xác định mối quan hệ đối tượng là phân biệt giữa Hiệp hội và Tập hợp. Mọi thứ khác đều rõ ràng. +1 từ tôi
Fouad Boukredine

28

Từ một bài đăng của Robert Martin trong comp.object :

Hiệp hội thể hiện khả năng của một thể hiện để gửi tin nhắn đến một thể hiện khác. Điều này thường được thực hiện với một con trỏ hoặc biến đối tượng tham chiếu, mặc dù nó cũng có thể được thực hiện như một đối số phương thức hoặc tạo một biến cục bộ.

//[Example:]

//|A|----------->|B|

class A
{
  private:
    B* itsB;
};

Tập hợp [...] là mối quan hệ toàn bộ / phần điển hình. Điều này hoàn toàn giống như một liên kết với ngoại lệ rằng các thể hiện không thể có mối quan hệ tập hợp theo chu kỳ (nghĩa là một phần không thể chứa toàn bộ).

//[Example:]

//|Node|<>-------->|Node|

class Node
{
  private:
    vector<Node*> itsNodes;
};

Thực tế rằng đây là tập hợp có nghĩa là các thể hiện của Node không thể tạo thành một chu kỳ. Do đó, đây là Tree of Nodes không phải là đồ thị của Nút.

Thành phần [...] hoàn toàn giống như Tập hợp ngoại trừ thời gian tồn tại của 'phần' được kiểm soát bởi 'toàn bộ'. Kiểm soát này có thể là trực tiếp hoặc bắc cầu. Đó là, "toàn bộ" có thể chịu trách nhiệm trực tiếp trong việc tạo hoặc phá hủy "phần" hoặc nó có thể chấp nhận một phần đã được tạo và sau đó chuyển nó cho một số người khác nhận trách nhiệm về nó.

//[Example:]

//|Car|<#>-------->|Carburetor|

class Car
{
  public:
    virtual ~Car() {delete itsCarb;}
  private:
    Carburetor* itsCarb
};

1
Định nghĩa này có bao nhiêu thẩm quyền? Nó có được hỗ trợ bởi các tác giả tiêu chuẩn UML không? Tôi nó được hỗ trợ bởi các công cụ?
rebierpost

1
Đó là Robert C. Martin. Đó là đủ thẩm quyền đối với tôi :-)
Heliac

21

Như những người khác đã nói, một hiệp hội là một mối quan hệ giữa các đối tượng, tập hợp và thành phần là các loại kết hợp.

Từ quan điểm thực hiện, một tập hợp có được bằng cách có một thành viên lớp bằng cách tham chiếu . Ví dụ: nếu lớp A tổng hợp một đối tượng của lớp B, bạn sẽ có một cái gì đó như thế này (trong C ++):

class A {
    B & element;
  // or B * element;
};

Các ngữ nghĩa của tập hợp là khi một đối tượng A bị phá hủy, đối tượng B mà nó đang lưu trữ sẽ vẫn tồn tại. Khi sử dụng thành phần, bạn có mối quan hệ mạnh mẽ hơn, thường bằng cách lưu trữ thành viên theo giá trị :

class A {
    B element;
};

Ở đây, khi một đối tượng A bị phá hủy, đối tượng B mà nó chứa cũng sẽ bị phá hủy. Cách dễ nhất để đạt được điều này là lưu trữ thành viên theo giá trị, nhưng bạn cũng có thể sử dụng một số con trỏ thông minh hoặc xóa thành viên trong hàm hủy:

class A {
    std::auto_ptr<B> element;
};

class A {
    B * element;

    ~A() {
        delete B;
    }
};

Điểm quan trọng là trong một chế phẩm, đối tượng container sở hữu một đối tượng chứa, trong khi trong tập hợp, nó tham chiếu nó.


8
Đây phải là câu trả lời duy nhất được chấp nhận. Thành phần không tồn tại trong C # và Java ngoại trừ với các kiểu nguyên thủy ... Tuy nhiên, bạn thấy các nhà phát triển của các ngôn ngữ đó "giải thích" thành phần. Thành phần có nghĩa là một đối tượng tồn tại bên trong khác. Trong Java và C # bạn thậm chí không thể làm điều đó, mọi thứ đều nằm trong heap và bạn chỉ cần giữ con trỏ đến nó, nó thực sự là tập hợp không phải là thành phần. C ++ cung cấp thành phần ..
Mọi người

14

Thật ngạc nhiên là bao nhiêu rắc rối tồn tại về sự khác biệt giữa ba khái niệm mối quan hệ liên kết , tập hợpthành phần .

Lưu ý rằng các thuật ngữ tổng hợpthành phần đã được sử dụng trong cộng đồng C ++, có thể trong một thời gian trước khi chúng được xác định là trường hợp liên kết đặc biệt trong Sơ đồ lớp UML.

Vấn đề chính là sự hiểu lầm phổ biến và đang diễn ra (ngay cả trong số các nhà phát triển phần mềm chuyên gia) rằng khái niệm thành phần ngụ ý sự phụ thuộc vòng đời giữa toàn bộ và các bộ phận của nó sao cho các bộ phận không thể tồn tại mà không có toàn bộ, bỏ qua thực tế là cũng có các trường hợp liên kết một phần với các bộ phận không thể chia sẻ trong đó các bộ phận có thể tách rời và tồn tại sự phá hủy của toàn bộ.

Theo như tôi có thể thấy, sự nhầm lẫn này có hai nguồn gốc:

  1. Trong cộng đồng C ++, thuật ngữ "tập hợp" được sử dụng theo nghĩa một lớp xác định một thuộc tính để tham chiếu các đối tượng của một lớp độc lập khác (xem, ví dụ, [1]), đó là ý nghĩa liên kết trong Biểu đồ lớp UML. Thuật ngữ "thành phần" được sử dụng cho các lớp xác định các đối tượng thành phần cho các đối tượng của chúng, chẳng hạn như khi phá hủy đối tượng hỗn hợp, các đối tượng thành phần này cũng đang bị phá hủy.

  2. Trong Sơ đồ lớp UML, cả "tổng hợp" và "thành phần" đã được định nghĩa là các trường hợp đặc biệt của các hiệp hội đại diện cho các mối quan hệ toàn bộ (đã được thảo luận trong triết học trong một thời gian dài). Trong định nghĩa của họ, sự khác biệt giữa "tập hợp" và "thành phần" dựa trên thực tế nếu nó cho phép chia sẻ một phần giữa hai hoặc nhiều wholes. Họ định nghĩa "các tác phẩm" là có các phần không thể chia sẻ (độc quyền), trong khi "tập hợp" có thể chia sẻ các phần của chúng. Ngoài ra, họ nói một số điều như sau: rất thường xuyên, nhưng không phải trong mọi trường hợp, các tác phẩm đi kèm với sự phụ thuộc vòng đời giữa toàn bộ và các phần của nó sao cho các phần không thể tồn tại mà không có toàn bộ.

Do đó, trong khi UML đã đặt các thuật ngữ "tổng hợp" và "thành phần" vào đúng ngữ cảnh (của các mối quan hệ toàn bộ), họ đã không quản lý để xác định chúng theo cách rõ ràng và rõ ràng, nắm bắt được trực giác của các nhà phát triển. Tuy nhiên, điều này không đáng ngạc nhiên vì có rất nhiều thuộc tính khác nhau (và các sắc thái triển khai) mà các mối quan hệ này có thể có và các nhà phát triển không đồng ý về cách triển khai chúng.

Xem thêm câu trả lời mở rộng của tôi cho câu hỏi SO tháng 4 năm 2009 được liệt kê dưới đây.

Và thuộc tính được giả định là định nghĩa "thành phần" giữa các đối tượng OOP trong cộng đồng C ++ (và niềm tin này vẫn được giữ vững): sự phụ thuộc vòng đời thời gian chạy giữa hai đối tượng liên quan (hỗn hợp và thành phần của nó), là không thực sự đặc trưng cho "thành phần" bởi vì chúng ta có thể có các phụ thuộc như vậy do tính toàn vẹn tham chiếu cũng trong các loại liên kết khác.

Chẳng hạn, mẫu mã sau đây cho "thành phần" đã được đề xuất trong câu trả lời SO :

final class Car {    
  private final Engine engine;

  Car(EngineSpecs specs) {
    engine = new Engine(specs);
  }

  void move() {
    engine.work();
  }
}

Người được hỏi tuyên bố rằng đó là đặc điểm của "thành phần" mà không lớp nào khác có thể tham chiếu / biết thành phần. Tuy nhiên, điều này chắc chắn không đúng với tất cả các trường hợp có thể có của "thành phần". Đặc biệt, trong trường hợp động cơ xe hơi, nhà sản xuất xe hơi, có thể được thực hiện với sự giúp đỡ của một lớp khác, có thể phải tham khảo động cơ để có thể liên hệ với chủ sở hữu của xe bất cứ khi nào có vấn đề với nó.

[1] http://www.learncpp.com/cpp-tutorial/103-aggregation/

Phụ lục - Danh sách không đầy đủ các câu hỏi được hỏi nhiều lần về thành phần so với tổng hợp trên StackOverflow

[ Tháng 4 năm 2009 ]
Tập hợp so với Thành phần [đóng chủ yếu dựa trên ý kiến]
[ Tháng 4 năm 2009 ]
Sự khác biệt giữa Mối quan hệ giữa Thành phần và Hiệp hội là gì?
[ Tháng 5 năm 2009 ]
Sự khác biệt giữa liên kết, tổng hợp và thành phần
[ Tháng 5 năm 2009 ]
Sự khác biệt giữa thành phần và tổng hợp là gì? [trùng lặp]
[ Tháng 10 năm 2009 ]
Sự khác biệt giữa tập hợp, thành phần và phụ thuộc là gì? [được đánh dấu là trùng lặp]
[ Tháng 11 năm 2010 ]
Hiệp hội so với Tập hợp [được đánh dấu là trùng lặp]
[Tháng 8 năm 2012 ] Sự
khác biệt triển khai giữa Tập hợp và Thành phần trong Java
[ Tháng 2 năm 2015 ]
UML - liên kết hoặc tổng hợp (đoạn mã đơn giản)


upvote cho danh sách không đầy đủ các câu hỏi liên tục.
Jacco

13

Hội

Hiệp hội đại diện cho mối quan hệ giữa hai lớp. Nó có thể là một chiều (một chiều) hoặc hai chiều (hai chiều)

ví dụ:

  1. một chiều

Khách hàng đặt hàng

  1. hai chiều

A đã kết hôn với B

B đã kết hôn với A

Tập hợp

Tập hợp là một loại kết hợp. Nhưng với các tính năng cụ thể. Tập hợp là mối quan hệ trong một lớp "toàn bộ" lớn hơn chứa một hoặc nhiều lớp "phần" nhỏ hơn. Ngược lại, lớp "phần" nhỏ hơn là một phần của lớp "toàn bộ" lớn hơn .

ví dụ:

câu lạc bộ có thành viên

Một câu lạc bộ ("toàn bộ") được tạo thành từ một số thành viên câu lạc bộ ("bộ phận"). Thành viên có cuộc sống bên ngoài câu lạc bộ. Nếu câu lạc bộ ("toàn bộ") chết, các thành viên ("bộ phận") sẽ không chết với nó. Bởi vì thành viên có thể thuộc nhiều câu lạc bộ ("toàn bộ").

Thành phần

Đây là một hình thức tổng hợp mạnh mẽ hơn. "Toàn bộ" chịu trách nhiệm cho việc tạo ra hoặc phá hủy các "bộ phận" của nó

Ví dụ:

Một trường có các khoa

Trong trường hợp này, trường học ("toàn bộ") đã chết, bộ phận ("bộ phận") sẽ chết cùng với nó. Bởi vì mỗi phần chỉ có thể thuộc về một "toàn bộ".


Trong trường hợp của tập đoàn. Tôi có nên sử dụng class Club(){ _member = new Member } hoặc vượt qua nó làm tài liệu tham khảoclass Club(){ addMember(Member member) { this._member = member } }
cuộn

12

Điều quan trọng là phải hiểu lý do tại sao chúng ta thậm chí nên bận tâm với việc sử dụng nhiều hơn một lần mối quan hệ. Lý do rõ ràng nhất là để mô tả mối quan hệ cha-con giữa các lớp (khi kết quả là cha mẹ đã xóa tất cả con của nó bị xóa), nhưng bất lực hơn, chúng tôi muốn phân biệt giữa liên kết và thành phần đơn giản để đặt ra các hạn chế ngầm đối với khả năng hiển thị và tuyên truyền thay đổi cho các lớp liên quan, một vấn đề đóng vai trò quan trọng trong việc hiểu và giảm độ phức tạp của hệ thống.

Hội

Cách trừu tượng nhất để mô tả mối quan hệ tĩnh giữa các lớp là sử dụng liên kết Hiệp hội, đơn giản chỉ ra rằng có một loại liên kết hoặc phụ thuộc giữa hai lớp trở lên.

Hiệp hội yếu

ClassA có thể được liên kết với ClassB để chỉ ra rằng một trong các phương thức của nó bao gồm tham số của thể hiện ClassB hoặc trả về thể hiện của ClassB.

Hiệp hội mạnh

ClassA cũng có thể được liên kết với ClassB để cho thấy rằng nó có tham chiếu đến thể hiện ClassB.

Tập hợp (Hiệp hội chia sẻ)

Trong trường hợp có mối quan hệ giữa ClassA (toàn bộ) và ClassB (một phần), chúng ta có thể cụ thể hơn và sử dụng liên kết tổng hợp thay vì liên kết liên kết, nhấn mạnh rằng ClassB cũng có thể được tổng hợp bởi các lớp khác trong ứng dụng ( do đó tập hợp còn được gọi là hiệp hội chia sẻ).

nhập mô tả hình ảnh ở đây

Điều quan trọng cần lưu ý là liên kết tổng hợp không nêu lên bất kỳ cách nào mà ClassA sở hữu ClassB cũng như không có mối quan hệ cha-con (khi cha mẹ xóa tất cả con của nó sẽ bị xóa do kết quả) giữa hai bên. Thật ra, hoàn toàn ngược lại! Liên kết tổng hợp thường được sử dụng để nhấn mạnh rằng ClassA không phải là bộ chứa độc quyền của ClassB, vì trên thực tế ClassB có một bộ chứa khác.

Tập hợp và liên kết Liên kết liên kết có thể thay thế liên kết tập hợp trong mọi tình huống, trong khi tập hợp không thể thay thế liên kết trong các tình huống chỉ có một "liên kết yếu" giữa các lớp, tức là ClassA có phương thức chứa tham số của ClassB nhưng ClassA thì không giữ tham chiếu đến thể hiện ClassB.

Martin Fowler đề nghị không nên sử dụng liên kết tổng hợp vì nó không có giá trị gia tăng và nó làm xáo trộn tính nhất quán, trích dẫn Jim Rumbaugh "Hãy nghĩ về nó như một giả dược mô hình".

Thành phần (Hiệp hội không chia sẻ)

Chúng ta nên cụ thể hơn và sử dụng liên kết thành phần trong các trường hợp ngoài mối quan hệ giữa ClassA và ClassB - còn có sự phụ thuộc vòng đời mạnh mẽ giữa hai bên, nghĩa là khi ClassA bị xóa thì ClassB cũng bị xóa

nhập mô tả hình ảnh ở đây

Liên kết thành phần cho thấy rằng một lớp (container, toàn bộ) có quyền sở hữu độc quyền đối với các lớp (s) khác, có nghĩa là đối tượng container và các phần của nó tạo thành mối quan hệ cha-con / s.

Không giống như liên kết và tổng hợp, khi sử dụng mối quan hệ thành phần, lớp tổng hợp không thể xuất hiện dưới dạng kiểu trả về hoặc kiểu tham số của lớp tổng hợp. Vì vậy, những thay đổi đối với lớp tổng hợp không thể truyền sang phần còn lại của hệ thống. Do đó, việc sử dụng thành phần hạn chế sự tăng trưởng phức tạp khi hệ thống phát triển.

Độ phức tạp của hệ thống

Độ phức tạp của hệ thống có thể được đo lường đơn giản bằng cách xem xét sơ đồ lớp UML và đánh giá các mối quan hệ liên kết, tổng hợp và thành phần. Cách để đo lường độ phức tạp là xác định có bao nhiêu lớp có thể bị ảnh hưởng bằng cách thay đổi một lớp cụ thể. Nếu lớp A phơi bày lớp B, thì bất kỳ lớp nào được sử dụng lớp A về mặt lý thuyết đều có thể bị ảnh hưởng bởi các thay đổi đối với lớp B. Tổng số lượng các lớp có khả năng bị ảnh hưởng cho mỗi lớp trong hệ thống là tổng độ phức tạp của hệ thống.

Bạn có thể đọc thêm trên blog của tôi: http://aviadezra.blogspot.com/2009/05/uml-association-aggregation-compocation.html



Câu trả lời tốt. 1) Câu hỏi cho ví dụ về thành phần: Leng and Hand (sáng tác) Person. nếu tôi tạo một lớp Thú và Ngủ thì Ngủ (agregation) Person; Ngủ (agregation) Động vật. Nó có đúng không? 2). Thành phần tay Người : class Person() { private hand = new Hand }. Người liên quan đến giấc ngủ class Person() { private sleep = new Sleep }Có hợp lệ sử dụng khóa "mới" trong chế độ Ngủ không? hoặc tôi nên vượt qua nó như là tài liệu tham khảo vì là sự kết hợp? class Person() { private Sleep _sleep; public addSleep(Sleep sleep) { this._sleep = sleep} }
cuộn

7

Thành phần (Nếu bạn xóa "toàn bộ", thì part part cũng bị xóa tự động.

  • Tạo các đối tượng của lớp hiện tại của bạn bên trong lớp mới. Điều này được gọi là thành phần vì lớp mới bao gồm các đối tượng của các lớp hiện có.

  • Thông thường sử dụng các biến thành viên bình thường.

  • Có thể sử dụng các giá trị con trỏ nếu lớp thành phần tự động xử lý phân bổ / thỏa thuận chịu trách nhiệm tạo / hủy các lớp con.

nhập mô tả hình ảnh ở đây

Thành phần trong C ++

#include <iostream>
using namespace std;
/********************** Engine Class ******************/
class Engine
{
    int nEngineNumber;
    public:
    Engine(int nEngineNo);
    ~Engine(void);
};
Engine::Engine(int nEngineNo)
{
    cout<<" Engine :: Constructor " <<endl;
}
Engine::~Engine(void)
{
    cout<<" Engine :: Destructor " <<endl;
}
/********************** Car Class ******************/
class Car
{
    int nCarColorNumber;
    int nCarModelNumber;
    Engine objEngine;
    public:
    Car (int, int,int);
    ~Car(void);
};
Car::Car(int nModelNo,int nColorNo, int nEngineNo):
nCarModelNumber(nModelNo),nCarColorNumber(nColorNo),objEngine(nEngineNo)
{
    cout<<" Car :: Constructor " <<endl;
}
Car::~Car(void)
{
    cout<<" Car :: Destructor " <<endl;
    Car
    Engine
    Figure 1 : Composition
}
/********************** Bus Class ******************/
class Bus
{
    int nBusColorNumber;
    int nBusModelNumber;
    Engine* ptrEngine;
    public:
    Bus(int,int,int);
    ~Bus(void);
};
Bus::Bus(int nModelNo,int nColorNo, int nEngineNo):
nBusModelNumber(nModelNo),nBusColorNumber(nColorNo)
{
    ptrEngine = new Engine(nEngineNo);
    cout<<" Bus :: Constructor " <<endl;
}
Bus::~Bus(void)
{
    cout<<" Bus :: Destructor " <<endl;
    delete ptrEngine;
}
/********************** Main Function ******************/
int main()
{
    freopen ("InstallationDump.Log", "w", stdout);
    cout<<"--------------- Start Of Program --------------------"<<endl;
    // Composition using simple Engine in a car object
    {
        cout<<"------------- Inside Car Block ------------------"<<endl;
        Car objCar (1, 2,3);
    }
    cout<<"------------- Out of Car Block ------------------"<<endl;
    // Composition using pointer of Engine in a Bus object
    {
        cout<<"------------- Inside Bus Block ------------------"<<endl;
        Bus objBus(11, 22,33);
    }
    cout<<"------------- Out of Bus Block ------------------"<<endl;
    cout<<"--------------- End Of Program --------------------"<<endl;
    fclose (stdout);
}

Đầu ra

--------------- Start Of Program --------------------
------------- Inside Car Block ------------------
Engine :: Constructor
Car :: Constructor
Car :: Destructor
Engine :: Destructor
------------- Out of Car Block ------------------
------------- Inside Bus Block ------------------
Engine :: Constructor
Bus :: Constructor
Bus :: Destructor
Engine :: Destructor
------------- Out of Bus Block ------------------
--------------- End Of Program --------------------

Tập hợp (Nếu bạn loại bỏ "toàn bộ", có thể tồn tại Phần Part - - Không có quyền sở hữu

  • Tập hợp là một loại thành phần cụ thể trong đó không có quyền sở hữu giữa đối tượng phức tạp và các tiểu dự án được ngụ ý. Khi một tập hợp bị phá hủy, các tiểu dự án không bị phá hủy.

  • Thông thường sử dụng các biến con trỏ / biến tham chiếu trỏ đến một đối tượng nằm ngoài phạm vi của lớp tổng hợp

  • Có thể sử dụng các giá trị tham chiếu trỏ đến một đối tượng nằm ngoài phạm vi của lớp tổng hợp

  • Không chịu trách nhiệm tạo / hủy các lớp con

nhập mô tả hình ảnh ở đây

Mã tổng hợp trong C ++

#include <iostream>
#include <string>
using namespace std;
/********************** Teacher Class ******************/
class Teacher
{
    private:
    string m_strName;
    public:
    Teacher(string strName);
    ~Teacher(void);
    string GetName();
};
Teacher::Teacher(string strName) : m_strName(strName)
{
    cout<<" Teacher :: Constructor --- Teacher Name :: "<<m_strName<<endl;
}
Teacher::~Teacher(void)
{
    cout<<" Teacher :: Destructor --- Teacher Name :: "<<m_strName<<endl;
}
string Teacher::GetName()
{
    return m_strName;
}
/********************** Department Class ******************/
class Department
{
    private:
    Teacher *m_pcTeacher;
    Teacher& m_refTeacher;
    public:
    Department(Teacher *pcTeacher, Teacher& objTeacher);
    ~Department(void);
};
Department::Department(Teacher *pcTeacher, Teacher& objTeacher)
: m_pcTeacher(pcTeacher), m_refTeacher(objTeacher)
{
    cout<<" Department :: Constructor " <<endl;
}
Department::~Department(void)
{
    cout<<" Department :: Destructor " <<endl;
}
/********************** Main Function ******************/
int main()
{
    freopen ("InstallationDump.Log", "w", stdout);
    cout<<"--------------- Start Of Program --------------------"<<endl;
    {
        // Create a teacher outside the scope of the Department
        Teacher objTeacher("Reference Teacher");
        Teacher *pTeacher = new Teacher("Pointer Teacher"); // create a teacher
        {
            cout<<"------------- Inside Block ------------------"<<endl;
            // Create a department and use the constructor parameter to pass the teacher to it.
            Department cDept(pTeacher,objTeacher);
            Department
            Teacher
            Figure 2: Aggregation
        } // cDept goes out of scope here and is destroyed
        cout<<"------------- Out of Block ------------------"<<endl;
        // pTeacher still exists here because cDept did not destroy it
        delete pTeacher;
    }
    cout<<"--------------- End Of Program --------------------"<<endl;
    fclose (stdout);
}

Đầu ra

--------------- Start Of Program --------------------
Teacher :: Constructor --- Teacher Name :: Reference Teacher
Teacher :: Constructor --- Teacher Name :: Pointer Teacher
------------- Inside Block ------------------
Department :: Constructor
Department :: Destructor
------------- Out of Block ------------------
Teacher :: Destructor --- Teacher Name :: Pointer Teacher
Teacher :: Destructor --- Teacher Name :: Reference Teacher
--------------- End Of Program --------------------

Bất cứ ai đã bỏ phiếu đã trả lời câu trả lời này. Bạn có thể vui lòng giải thích lý do bỏ phiếu không?
Saurabh Raoot

Điều thực sự làm tôi bối rối là, trong nhiều trường hợp, đó không phải là chủ sở hữu nắm giữ thứ đó, mà là thứ mà nó sở hữu "giữ" chủ sở hữu. Ví dụ: xe không có con trỏ loại Engine *, nhưng lớp Engine có thành viên loại Xe để lưu trữ chiếc xe sở hữu nó. Tôi hoàn toàn không hiểu nó đặc biệt là mối quan hệ uml của các lớp trong trường hợp này.
dudu

6

Vấn đề với những câu trả lời này là chúng là một nửa câu chuyện: họ giải thích rằng tập hợp và sáng tác là các hình thức liên kết, nhưng họ không nói nếu có thể một hiệp hội không phải là một trong số đó.

Tôi tập hợp dựa trên một số bài đọc ngắn gọn về nhiều bài đăng trên SO và một số tài liệu UML rằng có 4 hình thức cụ thể của liên kết lớp:

  1. thành phần: A is-comp-of-a B; B không tồn tại mà không có A, giống như một căn phòng trong nhà
  2. tập hợp: A có-a B; B có thể tồn tại mà không có A, giống như một học sinh trong lớp học
  3. phụ thuộc: A sử dụng-a B; không phụ thuộc vòng đời giữa A và B, như tham số gọi phương thức, giá trị trả về hoặc tạm thời được tạo trong khi gọi phương thức
  4. khái quát hóa: A là-a B

Khi mối quan hệ giữa hai thực thể không phải là một trong những thực thể này, nó chỉ có thể được gọi là "một liên kết" theo nghĩa chung của thuật ngữ và mô tả thêm các cách khác (lưu ý, rập khuôn, v.v.).

Tôi đoán là "hiệp hội chung" dự định sẽ được sử dụng chủ yếu trong hai trường hợp:

  • khi các chi tiết cụ thể của một mối quan hệ vẫn đang được thực hiện; mối quan hệ như vậy trong một sơ đồ nên được chuyển đổi càng sớm càng tốt với những gì nó thực sự là / sẽ là (một trong 4 cái còn lại).
  • khi một mối quan hệ không khớp với bất kỳ ai trong số 4 mối quan hệ được xác định trước bởi UML; hiệp hội "chung chung" vẫn cung cấp cho bạn cách thể hiện mối quan hệ "không phải là một trong những mối quan hệ khác", do đó bạn không bị mắc kẹt khi sử dụng mối quan hệ không chính xác với ghi chú "đây không thực sự là tổng hợp, đó chỉ là UML không có bất kỳ biểu tượng nào khác mà chúng ta có thể sử dụng "

1
Làm thế nào chính xác bạn sẽ thực hiện một hiệp hội chung nếu tất cả các tùy chọn khác được loại trừ? Nếu A không bao gồm B (Giá trị của B nằm trong A), A không phải là tổng hợp của B (Tham chiếu của B không nằm trong A), B không được thừa kế / nhận ra từ A cũng như B được sử dụng làm trả về, tham số hoặc trong chức năng sử dụng của A, bạn còn lại khá nhiều mà không liên quan gì.
Trưởng khoa P

1
@DeanP Nó chỉ có thể là chung cho thời điểm hiện tại, và sau đó sẽ được chuyển đổi thành một trong 4 (sau đó nó có thể thực hiện được); HOẶC nó có thể là một mối quan hệ không phù hợp với 4 như nói rằng bạn muốn một liên kết có nghĩa là "trông giống như", nếu không có một liên kết chung, bạn sẽ buộc phải sử dụng một trong 4, do đó, gây hiểu lầm cho người đọc, trong khi nếu bạn sử dụng chung chung bạn có thể sẽ chú thích nó hoặc đặt một ghi chú giải thích nó là gì và hầu hết mọi người chỉ đọc ghi chú nếu họ không hiểu biểu tượng đó;)
Oliver

5

Tôi nghĩ rằng liên kết này sẽ làm bài tập về nhà của bạn: http://ootips.org/uml-hasa.html

Để hiểu các thuật ngữ tôi nhớ một ví dụ trong những ngày lập trình đầu tiên của tôi:

Nếu bạn có một đối tượng 'bàn cờ' có chứa các đối tượng 'hộp' là thành phần vì nếu 'bàn cờ' bị xóa thì không có lý do gì để các hộp tồn tại nữa.

Nếu bạn có một đối tượng 'hình vuông' có đối tượng 'màu' và hình vuông bị xóa thì đối tượng 'màu' vẫn có thể tồn tại, đó là tập hợp

Cả hai đều là hiệp hội , sự khác biệt chính là khái niệm


5

Thành phần : Đây là nơi một khi bạn phá hủy một đối tượng (Trường học), một đối tượng khác (Lớp học) bị ràng buộc với nó cũng sẽ bị phá hủy. Cả hai không thể tồn tại độc lập.

Tập hợp : Đây là loại hoàn toàn trái ngược với Compositionliên kết ( ) ở trên khi bạn giết một đối tượng ( Company), đối tượng khác ( Employees) bị ràng buộc với nó có thể tự tồn tại.

Hội .
Thành phần và tập hợp là hai hình thức liên kết.


1
Nói đúng ra, nhân viên của một công ty không thể tồn tại nếu không có công ty. Đó là sự thật, bạn không giết người, nhưng họ không còn là nhân viên của công ty đó nữa. Vì vậy, tôi nghĩ rằng một sự tương tự tốt hơn sẽ là với Chi nhánh và Nhân viên, trong đó ngay cả khi chi nhánh đóng cửa, họ có thể tiếp tục là nhân viên của công ty.
Alexander

1
yup, hoàn toàn Đồng ý ... +1 Cảm ơn @AlexPopov đã chỉ ra điều đó. :)
Kicesangar

4
    Simple rules:
    A "owns" B = Composition : B has no meaning or purpose in the system 
    without A
    A "uses" B = Aggregation : B exists independently (conceptually) from A
    A "belongs/Have" B= Association; And B exists just have a relation
    Example 1:

    A Company is an aggregation of Employees.
    A Company is a composition of Accounts. When a Company ceases to do 
    business its Accounts cease to exist but its People continue to exist. 
    Employees have association relationship with each other.

    Example 2: (very simplified)
    A Text Editor owns a Buffer (composition). A Text Editor uses a File 
    (aggregation). When the Text Editor is closed,
    the Buffer is destroyed but the File itself is not destroyed.

3

Trong một câu rất đơn giản:
Tập hợp và Thành phần là tập hợp con của liên kết.

  • A sử dụng B -> đây là tổng hợp

  • A cần B -> là thành phần.

Đọc thêm ở đây .


2

Tôi muốn minh họa cách ba thuật ngữ được triển khai trong Rails. ActiveRecord gọi bất kỳ loại mối quan hệ giữa hai mô hình một association. Người ta sẽ không tìm thấy rất thường xuyên các điều khoản compositionaggregation, khi đọc tài liệu hoặc bài viết, liên quan đến ActiveRecord. Một liên kết được tạo bằng cách thêm một trong các macro của lớp kết hợp vào phần thân của lớp. Một số các macro này làbelongs_to , has_one, has_manyvv ..

Nếu chúng ta muốn thiết lập một compositionhoặc aggregation, chúng ta cần thêm belongs_tovào mô hình sở hữu (còn được gọi là con) và has_onehoặc has_manycho mô hình sở hữu (còn được gọi là cha mẹ). Khi chúng tôi thiết lập compositionhoặc aggregationphụ thuộc vào các tùy chọn chúng tôi chuyển đến belongs_tocuộc gọi trong mô hình con. Trước Rails 5, thiết lập belongs_tomà không có bất kỳ tùy chọn nào được tạo aggregation, đứa trẻ có thể tồn tại mà không cần cha mẹ. Nếu chúng ta muốn a composition, chúng ta cần khai báo rõ ràng điều này bằng cách thêm tùy chọn required: true:

class Room < ActiveRecord::Base
  belongs_to :house, required: true
end

Trong Rails 5, điều này đã được thay đổi. Bây giờ, khai báo một belongs_toliên kết tạo compositiontheo mặc định, đứa trẻ không thể tồn tại mà không có cha mẹ. Vì vậy, ví dụ trên có thể được viết lại thành:

class Room < ApplicationRecord
  belongs_to :house
end

Nếu chúng ta muốn cho phép đối tượng con tồn tại mà không có cha mẹ, chúng ta cần khai báo điều này rõ ràng thông qua tùy chọn optional

class Product < ApplicationRecord
  belongs_to :category, optional: true
end

2

Từ: Remo H. Jansen book Bắt đầu React: Learning TypeScript 2.x - Ấn bản thứ hai:

Chúng tôi gọi hiệp hội những mối quan hệ có đối tượng có vòng đời độc lập nơi không có quyền sở hữu đối tượng. Chúng ta hãy xem một ví dụ về một giáo viên và một học sinh. Nhiều học sinh có thể được liên kết với một giáo viên và một học sinh có thể được liên kết với nhiều giáo viên, nhưng cả hai đều có vòng đời độc lập (cả hai có thể tạo và xóa độc lập). Vì vậy, khi một giáo viên rời khỏi trường, chúng tôi không cần phải xóa bất kỳ học sinh nào và khi một học sinh rời khỏi trường, chúng tôi không cần phải xóa bất kỳ giáo viên nào.

Chúng tôi gọi tổng hợp những mối quan hệ có đối tượng có vòng đời độc lập, nhưng có quyền sở hữu và đối tượng con không thể thuộc về đối tượng cha mẹ khác. Hãy lấy một ví dụ về điện thoại di động và pin điện thoại di động. Một pin duy nhất có thể thuộc về một điện thoại, nhưng nếu điện thoại ngừng hoạt động và chúng tôi xóa nó khỏi cơ sở dữ liệu của chúng tôi, pin điện thoại sẽ không bị xóa vì nó vẫn có thể hoạt động. Vì vậy, trong tập hợp, trong khi có quyền sở hữu, các đối tượng có vòng đời của chúng

Chúng tôi sử dụng thuật ngữ thành phần để chỉ các mối quan hệ có đối tượng không có vòng đời độc lập và nếu đối tượng cha mẹ bị xóa, tất cả các đối tượng con cũng sẽ bị xóa. Hãy lấy một ví dụ về mối quan hệ giữa câu hỏi và câu trả lời. Các câu hỏi đơn có thể có nhiều câu trả lời và câu trả lời không thể thuộc về nhiều câu hỏi. Nếu chúng tôi xóa câu hỏi, câu trả lời sẽ tự động bị xóa.


1

Hiệp hội là một mối quan hệ giữa hai lớp riêng biệt và hiệp hội có thể thuộc bất kỳ loại nào nói một với một, một với có thể, vv Nó tham gia hai thực thể hoàn toàn riêng biệt.

Tập hợp là một hình thức liên kết đặc biệt, là mối quan hệ một chiều giữa các lớp (hoặc thực thể), ví dụ như các lớp Ví và Tiền. Ví có Tiền nhưng tiền không cần phải có Ví nhất thiết phải là mối quan hệ một chiều. Trong mối quan hệ này, cả hai mục có thể tồn tại nếu một mục khác kết thúc. Trong ví dụ của chúng tôi nếu lớp Wallet không có mặt, điều đó không có nghĩa là lớp Money không thể tồn tại.

Thành phần là một hình thức Tổng hợp hạn chế trong đó hai thực thể (hoặc bạn có thể nói các lớp) phụ thuộc rất nhiều vào nhau. Ví dụ như Con người và Trái tim. Một con người cần trái tim để sống và một trái tim cần một cơ thể Con người để tồn tại. Nói cách khác, khi các lớp (thực thể) phụ thuộc vào nhau và tuổi thọ của chúng là như nhau (nếu một người chết thì một người khác cũng vậy) thì đó là một thành phần. Lớp trái tim không có ý nghĩa nếu lớp Nhân loại không có mặt.


1

https://www.linkedin.com/pulse/types-relationships-object-oriented-programming-oop-sarah-el-dawody/

Thành phần: là mối quan hệ "một phần".

ví dụ động cơ của Cameron là một phần của xe, trái tim là một phần của cơ thể.

nhập mô tả hình ảnh ở đây

Hiệp hội: là một mối quan hệ kiểu có một

Ví dụ: giả sử chúng ta có hai lớp thì hai lớp này được gọi là mối quan hệ đã có mối quan hệ với nhau nếu cả hai thực thể này chia sẻ đối tượng của nhau cho một số công việc và đồng thời chúng có thể tồn tại mà không cần phụ thuộc lẫn nhau hoặc cả hai đều có trọn đời.

nhập mô tả hình ảnh ở đây

Ví dụ trên cho thấy mối quan hệ liên kết vì cả lớp Nhân viên và Người quản lý sử dụng đối tượng của nhau và cả vòng đời độc lập của riêng họ.

Tập hợp: dựa trên mối quan hệ "có-có" và đó là một hình thức liên kết đặc biệt

ví dụ, Sinh viên trực tuyến và địa chỉ trực tuyến. Mỗi học sinh phải có một địa chỉ để mối quan hệ giữa lớp Học sinh và lớp Địa chỉ sẽ là mối quan hệ kiểu kiểu Has Has-A nhưng ngược lại là không đúng.

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.