연관성, 집계 및 구성의 차이점은 무엇입니까?


389

연관성, 집계 및 구성의 차이점은 무엇입니까? 구현 측면에서 설명하십시오.


2
이것은 초보자 압도적 인 태드 수 있지만, UML 2 상부 구조 사양을 통해이라도 산책을 할 수 있습니다 omg.org/docs/formal/09-02-02.pdf의 협회 제 7.3.3
chickeninabiscuit

6
또한 UML 2에는 집계 또는 구성과 같은 요소가 없습니다 (UML 1.4에 있음). UML 2에서 집계 / 구성은 AggregationKind 특성이 공유 또는 복합으로 설정된 연관 요소로 구현됩니다.
chickeninabiscuit

SO에 대한 많은 답변이 이미 있습니다 : stackoverflow.com/search?q=aggregation+and+composition
lothar

2
유용한 기사 here codeproject.com/Articles/22769/…
GibboK

6
나는 이것이 이미 여러 번 대답되었다는 것을 알고 있지만, 내가 읽은 가장 좋은 설명은 이것입니다 : holub.com/goodies/uml/#composition
WLin

답변:


385

두 객체의 경우 FooBar의 관계를 정의 할 수 있습니다

연관성 -개체와 관계가 있습니다. Foo사용Bar

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

구성 -나는 물건을 소유하고 있으며 그 수명에 대한 책임이 있습니다. 때 Foo다이는, 그렇게Bar

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

집계 -다른 사람에게서 빌린 물건이 있습니다. 때 Foo다이는 Bar살 수 있습니다.

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

3
C # / 자바 코드 인 것 같습니다. 이 경우 연결 코드와 집계 코드가 동일합니다. 두 경우 모두 'bar'가 참조되었으며 Bar개체가 계속 작동 할 수 있습니다.
Ajay

@ Jeff Foster : 몇 가지 의심이 있습니다. Baz (Bar bar)에서 bar 객체를 인스턴스화하면 {bar = new Bar (); } 첫 번째 경우입니다. 그것은 여전히 ​​연합인가 아니면 지금 구성이 될 것인가?
Saket

21
@Ajay : 집계는 연관이 아닌 개체의 참조를 유지합니다. 따라서 구현의 차이.
ABCD

17
연결 은 메서드 매개 변수로 사용하는 것보다 조금 더 강력합니다. 귀하의 연결 코드 스 니펫은 종속성 관계에 더 해당한다고 생각합니다 . Martin Fowler 관련 기사
Ahmad Abdelghany

5
@AhmadAbdelghany가 맞습니다. 첫 번째 예는 의존 관계입니다. 세 번째는 연결 및 집계에 사용됩니다.
안드레 발렌티

122

나는이 질문에 C #으로 태그가 붙어 있지만 개념은 리디렉션 과 같은 일반적인 질문 입니다. 그래서 여기에 내 관점을 제공 할 것입니다 (자바가 더 편한 자바 관점에서 약간 바이어스되었습니다).

우리는 객체 지향적 성격을 생각할 때 항상 객체, 클래스 (오브젝트 블루 프린트) 및 이들 간의 관계를 생각합니다. 객체는 방법을 통해 서로 관련되어 있으며 상호 작용합니다. 즉, 한 클래스의 객체는 다른 클래스의 객체가 제공하는 서비스 / 방법을 사용할 수있다. 이런 종류의 관계를 협회 라고합니다 . .

집계 및 구성은 연결의 하위 집합이므로 특정 연결 사례입니다.

여기에 이미지 설명을 입력하십시오

  • 한 클래스의 집계 및 컴포지션 개체에서 다른 클래스의 "소유"개체 .
  • 그러나 미묘한 차이가 있습니다. 으로 구성 그것의 객체가 소유 클래스의 객체는 클래스를 소유하고있어 거기에 할 수있는 살 자신 있어요 (또한 소위 "죽음의 관계"). 집계 에서와 같이 종속 객체는 독립형 이며 소유 클래스의 객체가 죽은 경우에도 존재할 수 있는 소유 객체의 일부로 항상 존재합니다.
  • 따라서 컴포지션에서 소유 객체가 가비지 수집되면 소유 객체도 집계에 해당되지 않습니다.

혼란 스러운가?

구성 예 : 자동차 및 해당 자동차에 매우 특정한 엔진의 예를 고려하십시오 (즉, 다른 자동차에서는 사용할 수 없음). 자동차 간의 관계 유형SpecificEngine 클래스 Composition이라고합니다. Car 클래스의 개체는 SpecificEngine 클래스의 개체가 없으면 존재할 수 없으며 SpecificEngine의 개체는 Car 클래스가 없으면 의미가 없습니다. 간단히 말해서 Car 클래스는 SpecificEngine 클래스를 "소유"합니다.

집계 예 : 이제 Car 클래스와 Wheel 클래스를 고려하십시오 . 자동차가 작동하려면 Wheel 객체가 필요합니다. Car 객체는 Wheel 객체를 소유하지만 Car 객체가 없으면 Wheel 객체가 의미가 없다고 말할 수는 없습니다. 자전거, 트럭 또는 다른 자동차 개체에 매우 잘 사용될 수 있습니다.

요약하자면-

요약하자면 연관은 클래스가 다른 클래스에서 제공하는 기능을 사용할 때를 나타내는 데 사용되는 매우 일반적인 용어입니다. 우리는 하나의 부모 클래스 객체가 다른 자식 클래스 객체를 소유하고 그 자식 클래스 객체가 부모 클래스 객체없이 의미있게 존재할 수 없다면 구성이라고 말합니다. 가능하면 집계라고합니다.

자세한 내용은 여기를 참조하십시오. 나는 http://opensourceforgeeks.blogspot.in 의 저자이며 더 많은 컨텍스트를 위해 관련 게시물에 위의 링크를 추가했습니다.


8
5 년 이상 전에 이미 답변 된 질문에 답변을하려는 이유를 물어 보려고했지만 블로그 항목을 읽었으며 여기에 대한 답변보다 더 유익한 정보가되었습니다. 공감!
Donbhupi

2
@Donbhupi에 동의합니다. 귀하의 답변은 다른 많은 사람들보다 훨씬 유익하고 정확합니다.
zish

1
C # 및 Java 개발자가 해당 언어의 기본 유형에만 존재하는 경우 컴포지션을 사용한다고 주장하면 정말 재미 있습니다. 컴포지션을 실제로 이해하려면 객체가 다른 객체의 일부가 될 수있는 C ++를 사용해야합니다. 힙 메모리에 떠 다니고 서로 포인터를 잡고 컴포지션이 있다고 주장하는 것만이 아닙니다.
Everyone

@ 모두 당신과 같은 결론에 도달했지만 확실하지 않습니다. 예를 들어, 하나의 특정 클래스가 의미 적으로 소유 한 클래스가 하나 있지만 소유자가 가비지 수집기에 의해 이미 제거 된 후 소유 한 개체는 가비지 수집됩니다. 구성으로 간주됩니까?
Paulo André Haacke

관리되는 메모리를 사용하여 ac # 코드 내에서 구성을 가질 수 있습니까?
Paulo André Haacke

85

협회 는 관계의 일반화 된 개념입니다. 구성과 집계가 모두 포함됩니다.

컴포지션 ( 혼합 )은 간단한 객체 또는 데이터 유형을 단일 단위 로 래핑하는 방법입니다. 입니다. 컴포지션은 많은 기본 데이터 구조의 중요한 구성 요소입니다.

집계 ( 수집 )는 소유권을 의미하지 않는다는 점에서 일반적인 구성과 다릅니다. 컴포지션에서 소유 오브젝트가 파괴되면 포함 된 오브젝트도 파괴됩니다. 집계에서 이것은 반드시 사실이 아닙니다.

둘 다 대상 간의 관계를 나타내며 강도 만 다릅니다.

차이를 기억하는 트릭 :이 - ggregation 및 O WN - C O mpositoin을

여기에 이미지 설명을 입력하십시오

이제 다음 이미지를 관찰하십시오

처지

여기에 이미지 설명을 입력하십시오

유추:

구성 : 다음 그림은 이미지 구성입니다. 즉, 하나의 이미지를 만드는 개별 이미지를 사용합니다.
여기에 이미지 설명을 입력하십시오

집계 : 단일 위치에서 이미지 수집

여기에 이미지 설명을 입력하십시오

예를 들어, 한 대학교는 다양한 부서를 소유하고 있으며 각 부서에는 여러 명의 교수가 있습니다. 대학이 문을 닫으면 해당 부서는 더 이상 존재하지 않지만 해당 부서의 교수는 계속 존재합니다. 따라서 대학은 부서 구성으로 볼 수있는 반면 부서에는 교수가 모여 있습니다. 또한 교수는 둘 이상의 부서에서 일할 수 있지만 부서는 둘 이상의 대학에 속할 수 없습니다.


14
이 주제에 대해 많은 것을 읽은 후에이 대답은 가장 직관적으로 이해할 수있는 것입니다. 위키 백과에 게시해야합니다.
Jankapunkt

1
아름답게 표현되었습니다.
Sid

집계와 관련하여 "자식 개체는 단일 부모에 속합니다"라고 말합니다. 이것은 정확하지 않습니다. 공유 집계를 갖는 것이 유효한 UML입니다. 즉, 하위는 여러 상위에 속합니다. 교수가 하나 이상의 부서에서 일할 수 있다고 말하기 때문에 부서에 대한 교수의 집계로이 예를 인정합니다.
www.admiraalit.nl

@ www.admiraalit.nl AFAIK 공유 집계는 "자녀가 여러 부모에게 속함"을 의미하는 것이 아니라 다른 방식 일 뿐이며 여러 자녀가 ​​같은 부모에 속합니다. 부모가 죽어도 아이들이 더 오래 생존 할 수 있기 때문에 비 복합 집계입니다.
aderchox

65

종속성 (참조)
두 개체 사이에 개념적 연결이 없음을 의미합니다. 예 : EnrollmentService 객체는 Student 및 Course 객체를 참조합니다 (메소드 매개 변수 또는 반환 유형).

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

연관성 (has-a)
그것은 거의 항상 객체들 (연관된) 사이에 연결이 있음을 의미합니다. 주문 오브젝트 고객 오브젝트가 있습니다

public class Order {
    private Customer customer
}

집계 ( 하스 + 전체 파트)
두 개체간에 전체 파트 관계가있는 특수한 종류의 연관입니다. 그들은 서로없이 살 수 있습니다.

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

참고 : 가장 까다로운 부분은 일반 연관과 집계를 구별하는 것입니다. 솔직히 이것은 다른 해석에 개방적이라고 생각합니다.

컴포지션 (+ 전체 파트 + 소유권)
특수한 종류의 집계. 은 Apartment몇 가지로 구성되어있다 Room의. Room이 없으면 A 가 존재할 수 없습니다 Apartment. 아파트가 삭제되면 연결된 모든 객실도 삭제됩니다.

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

1
개체 관계를 결정하는 데있어 까다로운 부분은 협회와 집계를 구분하는 것입니다. 다른 모든 것은 분명하다. +1
Fouad Boukredine

28

comp.object의 Robert Martin 의 게시물 에서 :

연관은 한 인스턴스가 다른 인스턴스로 메시지를 보내는 기능을 나타냅니다. 이는 메소드 인수 또는 로컬 변수 작성으로 구현 될 수도 있지만 일반적으로 포인터 또는 참조 인스턴스 변수로 구현됩니다.

//[Example:]

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

class A
{
  private:
    B* itsB;
};

집계 [...]는 일반적인 전체 / 부분 관계입니다. 이는 인스턴스가 순환 집계 관계를 가질 수 없다는 것 (즉, 일부가 전체를 포함 할 수 없음)을 제외하고는 연관과 정확히 동일합니다.

//[Example:]

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

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

이것이 집계라는 사실은 Node의 인스턴스가주기를 형성 할 수 없음을 의미합니다. 따라서 이것은 노드의 그래프가 아닌 노드의 트리입니다.

컴포지션 [...]은 '부분'의 수명이 '전체'에 의해 제어된다는 점을 제외하면 집계와 정확히 같습니다. 이 제어는 직접적이거나 전이적일 수 있습니다. 즉, '전체'는 '파트'를 작성하거나 파기하는 데 직접적인 책임이 있거나 이미 작성된 파트를 승인 한 후 나중에 해당 파트를 책임지는 다른 전체에 전달할 수 있습니다.

//[Example:]

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

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

1
이 정의에는 얼마나 많은 권한이 있습니까? UML 표준 작성자가 지원합니까? 도구로 지원됩니까?
reinierpost

1
Robert C. Martin입니다. 그것은 저에게 충분한 권한입니다 :-)
Heliac

21

다른 사람들이 말했듯이 연결은 개체 간의 관계이며 집계와 구성은 연결 유형입니다.

구현 관점에서 볼 때 클래스 멤버 를 참조 하여 집계를 얻습니다 . 예를 들어, 클래스 A가 클래스 B의 개체를 집계하면 다음과 같은 것이 있습니다 (C ++).

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

집계의 의미는 오브젝트 A가 소멸 될 때 오브젝트 B가 저장하는 B 오브젝트가 여전히 존재한다는 것입니다. 컴포지션을 사용할 때 일반적으로 멤버 를 값 별로 저장하면 더 강한 관계 가 있습니다 .

class A {
    B element;
};

여기에서 A 오브젝트가 파괴되면 포함 된 B 오브젝트도 파괴됩니다. 이를 달성하는 가장 쉬운 방법은 멤버를 값으로 저장하는 것입니다. 그러나 스마트 포인터를 사용하거나 소멸자에서 멤버를 삭제할 수도 있습니다.

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

class A {
    B * element;

    ~A() {
        delete B;
    }
};

중요한 점은 컴포지션에서 컨테이너 객체가 포함 된 객체를 소유 하는 반면 집계에서는 컨테이너 객체를 참조 한다는 것입니다.


8
이것이 유일하게 허용되는 답변이어야합니다. 프리미티브 유형을 제외하고 C # 및 Java에는 컴포지션이 존재하지 않습니다. 그러나 해당 언어의 개발자가 컴포지션을 "설명"합니다. 구성은 개체가 다른 개체 안에 존재 함을 의미합니다. Java와 C #에서는 그것을 할 수 없으며 모든 것이 힙에 있고 포인터를 잡고 있습니다. 실제로 구성이 아닌 집계입니다. C ++는 컴포지션을 제공합니다.
누구나

14

세 가지 관계 개념 연관 , 집계구성 간의 구별에 대해 혼란이 얼마나 많은지 놀랍습니다 .

집계구성 이라는 용어 는 아마도 C ++ 커뮤니티 에서 UML 클래스 다이어그램에서 특수한 연관 사례로 정의되기 전에 한동안 사용되었습니다 .

주된 문제는 구성 개념이 전체 부품과 부품 사이의 수명주기 의존성을 암시하여 부품이 전체없이 존재할 수없고 부품이 존재하지 않는다는 사실을 무시한다는 광범위하고 지속적인 오해 (전문 소프트웨어 개발자들 사이에서도)입니다. 공유 할 수없는 부품과 부품이 분리되어 전체의 파괴에서 살아남을 수있는 부품 전체의 경우.

내가 볼 수있는 한,이 혼란은 두 가지 뿌리를 가지고 있습니다 :

  1. C ++ 커뮤니티에서 "집계"라는 용어 는 UML 클래스 다이어그램 의 연관 의미 인 다른 독립 클래스 (예 : [1] 참조)의 오브젝트를 참조하기위한 속성을 정의하는 클래스의 의미로 사용되었습니다 . "컴포지션"이라는 용어는 객체에 대한 구성 요소 객체를 정의하는 클래스에 사용되었습니다. 예를 들어 복합 객체가 파괴 될 때 이러한 구성 요소 객체도 파괴됩니다.

  2. UML 클래스 다이어그램에서 "집계"및 "구성"은 부분적으로 전체 관계를 나타내는 특수한 연관 사례로 정의되었습니다 (철학에서 오랫동안 논의되어 왔음). 정의에서 "집계"와 "구성"의 차이점은 둘 이상의 전체간에 부분을 공유 할 수 있는지에 따라 결정됩니다. "합성"은 공유 할 수없는 (독점) 파트를 갖는 것으로 정의하지만 "집계"는 파트를 공유 할 수 있습니다. 또한 다음과 같이 말합니다. 모든 경우에 있어서는 아니지만 컴포지션은 전체와 해당 파트 사이에 수명주기 종속성이있어서 파트가 전체 없이는 존재할 수 없습니다.

따라서 UML은 "전반적인 관계"라는 올바른 맥락에서 "집합"과 "구성"이라는 용어를 사용했지만 개발자의 직관을 포착하여 명확하고 모호하지 않은 방식으로 정의하지는 못했습니다. 그러나 이러한 관계가 가질 수있는 다양한 속성 (및 구현 뉘앙스)이 많고 개발자가이를 구현하는 방법에 동의하지 않기 때문에 이는 놀라운 일이 아닙니다.

또한 2009 년 4 월 SO 질문에 대한 확장 된 답변 을 참조하십시오 .

그리고 C ++ 커뮤니티에서 OOP 객체들 사이에 "구성"을 정의한다고 가정 한 속성 (그리고 이러한 믿음은 여전히 ​​널리 유지되고 있음) : 두 관련 객체들 (컴포지트와 그 구성 요소) 사이의 런타임 수명주기 의존성은 다음과 같습니다. 다른 유형의 연관에서도 참조 무결성으로 인해 이러한 종속성을 가질 수 있기 때문에 실제로는 "구성"의 특성이 아닙니다.

예를 들어 SO 구성에서 "composition"에 대한 다음 코드 패턴이 제안되었습니다 .

final class Car {    
  private final Engine engine;

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

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

응답자는 다른 클래스가 컴포넌트를 참조 / 알 수없는 것이 "구성"의 특성이라고 주장했다. 그러나 이것은 가능한 모든 "조성"사례에 해당되는 것은 아닙니다. 특히, 자동차 엔진의 경우, 다른 클래스의 도움으로 구현 될 수있는 자동차 제조사는 문제가있을 때마다 자동차 소유자에게 연락 할 수 있도록 엔진을 참조해야 할 수도 있습니다.

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

부록-StackOverflow의 구성과 집계에 대한 반복되는 질문의 불완전한 목록

[ 2009 년 4 월 ]
집계와 구성 [주로 의견 기반으로 마감]
[ 2009 년 4 월 ]
구성과 연관 관계의 차이점은 무엇입니까?
[ 2009 년 5 월 ]
연관, 집계 및 컴포지션 의 차이
[ 2009 년 5 월 ]
컴포지션과 집계의 차이점은 무엇입니까? [중복]
[ 2009 년 10 월 ]
집계, 구성 및 종속성의 차이점은 무엇입니까? [중복으로 표시]
[ 2010 년 11 월 ]
협회 대 집계 [중복으로 표시]
[2012 년 8 월 ]
Java에서 집계와 컴포지션의 구현 차이
[ 2015 년 2 월 ]
UML-연관 또는 집계 (간단한 코드 스 니펫)


반복적으로 묻는 질문의 불완전한 목록에 대해 찬성
Jacco

13

협회

연결은 두 클래스 간의 관계를 나타냅니다. 단방향 (단방향) 또는 양방향 (양방향) 일 수 있습니다.

예를 들면 다음과 같습니다.

  1. 단방향

고객 주문

  1. 양방향

A는 B와 결혼

B는 A와 결혼

집합

집계는 일종의 연관성입니다. 그러나 특정 기능이 있습니다. 집단은 하나의 더 큰 "전체"클래스의 관계가 하나 이상의 더 작은 "파트"클래스를 포함하는 것입니다. 반대로, 더 작은 "파트"클래스는 "전체"더 큰 클래스의 일부입니다. .

예를 들면 다음과 같습니다.

클럽 회원이

클럽 ( "전체")은 여러 클럽 회원 ( "파트")으로 구성되어 있습니다. 클럽 ( "전체")이 죽으면 회원 ( "파트")은 클럽과 함께 죽지 않습니다. 회원은 여러 클럽 ( "전체")에 속할 수 있기 때문입니다.

구성

"전체"는 "파트"의 생성 또는 파괴를 담당합니다.

예를 들면 다음과 같습니다.

학교에는 부서가 있습니다

이 경우 학교 ( "전체")는 죽어야하고 부서 ( "부품")도 함께 죽게됩니다. 각 부분은 하나의 "전체"에만 속할 수 있기 때문입니다.


집계의 경우. class Club(){ _member = new Member } 참고로 사용 하거나 전달 해야합니까 class Club(){ addMember(Member member) { this._member = member } }

12

왜 우리가 두 번 이상의 관계 라인을 사용하여 귀찮게 해야하는지 이해하는 것이 중요합니다. 가장 명백한 이유는 클래스 간의 부모-자식 관계를 설명하는 것입니다 (부모가 삭제 된 모든 자식이 결과적으로 삭제됨). 그러나 더 무의식적으로 가시성 및 시스템 복잡성 을 이해 하고 줄이는 데 중요한 역할을하는 관련 클래스에 대한 변경 사항 전파

협회

클래스 간의 정적 관계를 설명하는 가장 추상적 인 방법은 Association 링크를 사용하는 것입니다.이 링크는 단순히 두 종류 이상의 링크 또는 일종의 링크가 있음을 나타냅니다.

약한 협회

ClassA의 메소드 중 하나가 ClassB 인스턴스의 매개 변수를 포함하거나 ClassB의 인스턴스를 리턴 함을 나타 내기 위해 ClassA가 ClassB에 링크 될 수 있습니다.

강력한 협회

ClassA는 ClassB 인스턴스에 대한 참조를 보유 함을 나타 내기 위해 ClassB에 링크 될 수도 있습니다.

집계 (공동 협회)

ClassA (전체)와 ClassB (파트) 사이에 부분 관계가있는 경우 더 구체적으로 지정할 수 있으며 연관 링크 대신 집계 링크를 사용하여 응용 프로그램의 다른 클래스에서 클래스 B를 집계 할 수도 있음을 강조합니다 ( 따라서 집계는 공유 연결이라고도합니다.

여기에 이미지 설명을 입력하십시오

집계 링크는 ClassA가 ClassB를 소유하는 방식이나 부모-자식 관계 (부모가 모든 자식을 삭제 한 경우 결과적으로 삭제됨)가 둘 사이에 존재하지 않는다는 점에 유의해야합니다. 실제로는 정반대입니다! 실제로 ClassB에는 다른 컨테이너가 있으므로 ClassA가 ClassB의 독점 컨테이너가 아니라는 점을 강조하는 데 일반적으로 집계 링크가 사용됩니다.

어 그리 게이션 vs 연관 어소시에이션 링크는 모든 상황에서 어 그리 게이션 링크를 대체 할 수 있지만, 클래스 사이에 '약한 링크'만있는 경우 어 그리 게이션은 어 그리 게이션을 대체 할 수 없습니다. ClassB 인스턴스에 대한 참조를 보유하십시오.

마틴 파울러 (Martin Fowler)는 집계 링크는 부가 가치가없고 일관성을 방해하기 때문에 전혀 사용해서는 안된다고 짐 Rumbaugh를 인용했다.

작문 (비공유 협회)

ClassA와 ClassB 사이의 일부 관계에 더해보다 구체적이어야하고 컴포지션 링크를 사용해야합니다. 둘 사이에 수명주기 종속성이 강합니다. 즉, ClassA가 삭제되면 ClassB도 삭제됩니다.

여기에 이미지 설명을 입력하십시오

컴포지션 링크는 클래스 (컨테이너, 전체)가 다른 클래스 (파트)에 대해 독점 소유권을 가지고 있음을 보여줍니다. 즉, 컨테이너 객체와 해당 파트가 부모-자식 관계를 구성합니다.

결합 및 집계와 달리 작성 관계를 사용할 때 작성된 클래스는 복합 클래스의 리턴 유형 또는 매개 변수 유형으로 나타날 수 없습니다. 따라서 작성된 클래스의 변경 사항은 나머지 시스템으로 전파 될 수 없습니다. 결과적으로, 구성의 사용은 시스템이 성장함에 따라 복잡성 증가를 제한합니다.

측정 시스템의 복잡성

UML 클래스 다이어그램을보고 연관성, 집계 및 구성 관계 라인을 평가하여 시스템 복잡성을 간단히 측정 할 수 있습니다. 복잡성을 측정하는 방법은 특정 클래스를 변경하여 영향을받을 수있는 클래스 수를 결정하는 것입니다. 클래스 A가 클래스 B를 노출하는 경우 클래스 A를 사용하는 주어진 클래스는 이론적으로 클래스 B의 변경에 의해 영향을받을 수 있습니다. 시스템의 모든 클래스에 영향을 줄 수있는 클래스 수의 합계는 전체 시스템 복잡성입니다.

내 블로그에서 더 자세한 내용을 읽을 수 있습니다 : http://aviadezra.blogspot.com/2009/05/uml-association-aggregation-composition.html



좋은 대답입니다. 1) 구성 예제에 대한 질문 : Leng and Hand (composition) Person. 내가 Animal and Sleep 클래스를 만들면 Sleep (agregation) Person; 수면 (집합) 동물. 맞습니까? 2). 손 구성 사람 : class Person() { private hand = new Hand }. 수면 어 그리 게이션 사람 수면 class Person() { private sleep = new Sleep }에서 "새"키를 사용하는 것이 유효합니까? 또는 집계이기 때문에 참조로 전달해야합니까? class Person() { private Sleep _sleep; public addSleep(Sleep sleep) { this._sleep = sleep} }

7

구성 ( "전체"를 제거하면 "부분"도 자동으로 제거됨 – "소유권")

  • 새 클래스 안에 기존 클래스의 객체를 만듭니다. 새 클래스는 기존 클래스의 객체로 구성되어 있기 때문에이를 컴포지션이라고합니다.

  • 일반적으로 일반 멤버 변수를 사용하십시오.

  • 작성 클래스가 서브 클래스 작성 / 파괴를 담당하는 할당 / 할당 해제를 자동으로 처리하는 경우 포인터 값을 사용할 수 있습니다.

여기에 이미지 설명을 입력하십시오

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

산출

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

집계 ( "전체"를 제거하면 "부품"이있을 수 있음 – "소유권 없음")

  • 집계는 복합 객체와 하위 객체 간의 소유권이 암시되지 않는 특정 유형의 컴포지션입니다. 집계가 파괴 될 때 하위 오브젝트는 파괴되지 않습니다.

  • 일반적으로 집계 클래스의 범위를 벗어나는 객체를 가리키는 포인터 변수 / 참조 변수를 사용하십시오.

  • 집계 클래스의 범위를 벗어나는 객체를 가리키는 참조 값을 사용할 수 있습니다.

  • 서브 클래스 생성 / 파괴에 대한 책임 없음

여기에 이미지 설명을 입력하십시오

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

산출

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

누구든지이 답변에 투표했습니다. 투표 거부 이유를 설명해 주시겠습니까?
Saurabh Raoot

실제로 나를 혼동하는 것은 많은 경우에 소유자가 소유물을 소유하는 것이 아니라 소유주가 "소유자를 보유"하는 것입니다. 예를 들어, 자동차에는 Engine * 유형 포인터가 없지만 Engine 클래스에는 자동차를 소유 한 자동차를 저장하는 Car 유형 멤버가 있습니다. 특히이 경우 클래스의 uml 관계를 이해하지 못합니다.
dudu

6

이 답변의 문제는 반 이야기라는 것입니다. 그들은 집계와 구성이 연결의 형태라고 설명하지만, 연결이 그 둘 중 어느 것도 될 수 없다고 말하지는 않습니다.

나는 SO에 대한 많은 게시물에 대한 간단한 읽은 내용과 4 가지 주요 클래스 형태의 클래스 연관성이 있다는 UML 문서를 기반으로 수집합니다.

  1. 구성 : A는 B로 구성되고; B는 집이없는 방처럼 A가 없으면 존재하지 않습니다
  2. 집합 : A는 B; B는 교실에서 학생처럼 A 없이도 존재할 수 있습니다
  3. 의존성 : A는 B를 사용한다; 메소드 호출 매개 변수, 리턴 값 또는 메소드 호출 중에 작성된 임시와 같이 A와 B 사이의 라이프 사이클 종속성이 없음
  4. 일반화 : A is-a B

두 엔티티 사이의 관계가 이들 중 하나가 아닌 경우, 용어라는 일반적인 의미에서 "연관"이라고 할 수 있으며 다른 방법 (참고, 고정 관념 등)을 추가로 설명합니다.

내 생각 엔 "일반적인 연관성"은 두 가지 상황에서 주로 사용된다는 것입니다.

  • 관계의 세부 사항이 여전히 해결되고있을 때; 다이어그램의 이러한 관계는 가능한 한 빨리 실제 상태로 변환되어야합니다 (다른 4 가지 중 하나).
  • 관계가 UML에 의해 미리 결정된 것들 중 어느 것과도 일치하지 않을 때; "일반"연결은 여전히 ​​"다른 것 중 하나"가 아닌 관계를 나타내는 방법을 제공하므로 "이것은 실제로 집계되지 않습니다. UML에 불과합니다"라는 메모와의 잘못된 관계를 사용하지 않아도됩니다. 사용할 수있는 다른 기호가 없습니다 "

1
다른 모든 옵션이 배제 된 경우 어떻게 일반 연관을 구현 하시겠습니까? A가 B로 구성되지 않은 경우 (B의 값은 A에 있음), A는 B의 집계가 아니고 (B의 참조는 A에 있지 않음), B는 A에서 상속 / 실현되지 않으며 B는 반환, 매개 변수 또는 내부로 사용되지 않습니다 A의 함수 사용법, 당신은 관계없이 거의 남아 있습니다.
Dean P

1
@DeanP 당분간은 일반적 일 수 있으며 나중에 4 중 하나로 변환됩니다 (그런 다음 구현 가능하게 됨). 또는 "모양"을 의미하는 연관을 원한다고 말하는 것과 같이 4에 맞지 않는 관계 일 수 있습니다. 일반적인 연관이 없으면 4 중 하나를 사용해야하므로 독자를 오도하게됩니다. 일반적으로 당신은 그것을 주석을 달거나 그것이 무엇인지 설명하는 메모를 넣을 것입니다. 대부분의 사람들은 기호를 이해하지 못하는 경우에만 메모를 읽습니다.)
Oliver

5

나는이 링크가 당신의 숙제를 할 것이라고 생각합니다 : http://ootips.org/uml-hasa.html

초기 프로그래밍 시절의 예를 기억하는 용어를 이해하려면 :

'체스 보드'가 삭제되면 더 이상 상자가 존재할 이유가 없기 때문에 컴포지션 인 '상자'개체를 포함하는 '체스 보드'개체가있는 경우 더 이상 존재하지 않습니다.

'색상'개체가있는 '사각형'개체가 있고 사각형이 삭제 된 경우 '색상'개체가 여전히 존재할 수 있습니다. 즉 집계

둘 다 협회 이고 주요 차이점은 개념적입니다.


5

구성 : 일단 객체 (학교)를 파괴하면 다른 객체 (교실)에 묶인 객체도 파괴됩니다. 둘 다 독립적으로 존재할 수 없습니다.

어 그리 게이션 (Aggregation) : 이것은 Composition일단 객체 ( Company) 를 죽인 후에 그 객체 Employees에 바인딩 된 다른 객체 ( )가 단독으로 존재할 수 있는 위의 ( ) 연관과 정반대입니다 .

협회 .
구성과 집계는 두 가지 형태의 연결입니다.


1
엄밀히 말하면 회사의 직원은 회사 없이는 존재할 수 없습니다. 사실, 당신은 사람들을 죽이지 않지만 더 이상 그 회사의 직원이 아닙니다. 따라서 지점 및 직원과 더 나은 유추를 할 수 있다고 생각합니다. 지점이 닫히더라도 계속 회사의 직원 일 수 있습니다.
Alexander

1
그렇습니다. 동의합니다 ... +1 @AlexPopov에게 감사합니다. :)
Kulasangar

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.


2

Rails에서 세 가지 용어가 어떻게 구현되는지 설명하고 싶습니다. ActiveRecord는 두 모델 사이의 모든 유형의 관계를 호출합니다 association. 설명서 나 기사를 읽을 때 ActiveRecord와 관련된 용어 composition와 용어를 자주 찾지 못할 것 aggregation입니다. 연관 클래스 매크로 중 하나를 클래스 본문에 추가하여 연관이 작성됩니다. 이 매크로 중 일부는 belongs_to, has_one, has_many

우리가 설정하려는 경우 composition또는 aggregation, 우리는 추가 할 필요가 belongs_to소유 모델 (또한 아이)와에 has_one또는 has_many소유 모델 (또한 부모)에. 하위 모델에서 통화에 전달하는 옵션 을 설정 composition했거나 aggregation의존합니다 belongs_to. Rails 5 이전에는 belongs_to옵션을 만들지 않고 설정하기 전에 aggregation자식이 부모없이 존재할 수있었습니다. 를 원한다면 composition옵션을 추가하여 명시 적으로 선언해야했습니다 required: true.

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

Rails 5에서는 이것이 변경되었습니다. 이제 belongs_to연결을 선언하면 composition기본적으로 연결이 만들어 지므로 부모가 없으면 자식이 존재할 수 없습니다. 따라서 위 예제는 다음과 같이 다시 작성할 수 있습니다.

class Room < ApplicationRecord
  belongs_to :house
end

자식 객체가 부모없이 존재하게하려면 옵션을 통해 명시 적으로 선언해야합니다. optional

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

2

From : Remo H. Jansen 책“Reacting React : Learning TypeScript 2.x-Second Edition”:

협회에 전화개체 소유권이없는 개체의 독립 수명주기를 갖는 관계를 합니다. 교사와 학생의 예를 봅시다. 여러 학생이 단일 교사와 연관 될 수 있고 단일 학생이 여러 교사와 연관 될 수 있지만 둘 다 독립적 인 수명주기가 있습니다 (둘 다 독립적으로 작성 및 삭제 가능). 따라서 교사가 학교를 떠날 때 학생을 삭제할 필요가 없으며 학생이 학교를 떠날 때 교사를 삭제할 필요가 없습니다.

우리는 집계를 호출개체 수명주기가 독립적이지만 개체가 있고 자식 개체가 다른 부모 개체에 속할 수없는 관계를 합니다. 휴대 전화와 휴대 전화 배터리를 예로 들어 보겠습니다. 단일 배터리는 전화기에 속할 수 있지만 전화기가 작동을 멈추고 데이터베이스에서 삭제하면 전화기 배터리는 여전히 작동하기 때문에 삭제되지 않습니다. 따라서 집계시 소유권이있는 동안 개체의 수명주기는

컴포지션 이라는 용어 는 개체에 독립 수명주기가없는 관계를 나타내며 부모 개체가 삭제되면 모든 자식 개체도 삭제됩니다. 질문과 답변의 관계를 예로 들어 봅시다. 단일 질문에는 여러 개의 답변이있을 수 있으며 답변은 여러 질문에 속할 수 없습니다. 질문을 삭제하면 답변이 자동으로 삭제됩니다.


1

협회 은 두 개의 개별 클래스 간의 관계이며 연관은 일대일, 일대일 등 모든 유형의 관계 일 수 있습니다. 두 개의 완전히 별개의 엔티티를 결합합니다.

집계 는 클래스 (또는 엔티티) 사이의 단방향 단방향 관계 (예 : Wallet 및 Money 클래스) 인 특수한 연관 형식입니다. 월렛에는 돈이 있지만 돈은 반드시 월렛을 가질 필요가 없으므로 단방향 관계입니다. 이 관계에서 다른 항목이 종료되면 두 항목이 모두 생존 할 수 있습니다. 이 예에서 Wallet 클래스가 존재하지 않는다고해서 Money 클래스가 존재할 수 없다는 의미는 아닙니다.

컴포지션 은 두 엔터티 (또는 클래스를 말할 수 있음)가 서로 의존하는 제한된 집계 형식입니다. 예를 들어 인간과 심장. 인간은 살기 위해 마음이 필요하고, 살아 남기 위해서는 사람의 몸이 필요합니다. 다시 말해서, 계급 (엔티티)이 서로 의존하고 그들의 수명이 동일한 경우 (하나가 죽으면 다른 하나도) 그 구성이됩니다. 인간 계급이 존재하지 않으면 심장 계급은 의미가 없습니다.


1

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

구성 : "부분"관계입니다.

예를 들어 "엔진은 자동차의 일부", "마음은 신체의 일부"입니다.

여기에 이미지 설명을 입력하십시오

협회 : "하스"유형 관계

예를 들어, 두 개의 클래스가 있다고 가정하고이 두 엔티티가 둘 다 어떤 작업에 대해 서로의 객체를 공유하고 동시에 서로의 종속성없이 존재할 수 있거나 둘 다 갖는 경우 "하스"관계라고합니다 자신의 평생.

여기에 이미지 설명을 입력하십시오

위의 예제는 직원과 관리자 클래스 모두가 서로의 객체와 자신의 독립적 인 수명주기를 사용하기 때문에 연관 관계를 보여줍니다.

집계 : "has-a"관계를 기반으로하며 \\ a 특수한 연관 형식입니다.

예를 들어 "학생"및 "주소"입니다. 각 학생은 주소를 가지고 있어야 학생 클래스와 주소 클래스 간의 관계는“Has-A”유형 관계가되지만 그 반대도 마찬가지입니다.

여기에 이미지 설명을 입력하십시오

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.