'Association'에 해당되는 글 3건

  1. 2008.03.23 [S/E] Term confusion - Association and Object Association 4 by Dansoonie
  2. 2008.03.17 [S/E] How is Aggregation and Composition different? 11 by Dansoonie
  3. 2008.02.19 [C++] How to make Circular Dependency work??? by Dansoonie
This post is dedicated to 바람, who is currently confused with the terms that I used on March 17th's post(How is Aggregation and Composition different?) and which Wikipedia uses.

I am assuming that all the confusion started from the word object association which is a term used in Object-Oriented programming paradigm. According to Wikipedia, object association is described as a concept of building objects from other objects [1]. My understanding is that this word has nothing to do with the term association which describes the relationship between objects. The term association is used to define the relationship among objects when their scope does not overlap from one another. The concept of object association is also used to define the relationship among objects, but only when their scope is nested inside one another.

Recall that association is also called a "knows-a relationship" while aggregation and composition is called a "has-a relationship". I personally think that these simplified terms are descriptive enough for everyone to understand this topic better.

If I would elaborate more on association, association provides a mechanism to an object to interact between other objects within its own scope. If my explanation isn't clear for you and wish for more information, refer to [2]. For aggreation and composition, refer to [3].

Basically, my point here is that not to be confused with association among objects and the concept of object association.


References
[1] http://en.wikipedia.org/wiki/Object_association
[2] http://en.wikipedia.org/wiki/Association_%28object-oriented_programming%29
[3] http://en.wikipedia.org/wiki/Object_composition#Aggregation
Posted by Dansoonie
대학교때 C++을 통해서 객체지향을 배우면서 Class와 Class와의 관계를 어떻게 정의하고 코드로 어떻게 표현하는지 배웠다. Class와 class와의 관계중에 가장 기본적이고 대표적인것이 아마도 Aggregation과 Association일것이다. 학교에서 객체지향에 대한 개념 배울때 그것만 중점적으로 배워서 그런지 (사실 처음 배울때는 그런 관계도 명확히 하는것이 어렵기도 하지) 아직까지도 UML 그릴때 aggregation과 association만 사용한다.

하지만 요즘에 회사에서 일하면서 간혹 class diagram을 그리기 위해 공짜 UML 툴 중에 Star UML이라는 Tool을 사용하는데, 그 툴을 통해서 평소에 알지 못했던 Composition이라는 관계를 class간에 정의 할 수 있음을 발견하였다. Composition과 Aggregation의 관계를 보여주는 기호도 비슷했다.


그렇다면 이 둘의 차이점은 무엇인가? 보통 Association은 "knows-a" 관계라고 부른다. 반면 Aggregation은 "has-a" 관계라고 배워왔다. 하지만 내가 이해한 composition에 대해서 우선적으로 대략적으로 말하자면 그동안 내가 알아왔던 aggregation이 사실은 composition이고, aggregation은 association의 탈을 쓴 composition이다.

내가 그동안 이해했던 aggregation이라는것은 다음과 같다.
어떤 클래스가 다른 클래스를 member로 가지고 있다면 그것은 "has-a"관계이고 곧 aggregation이다. 하지만 이것이 composition이고, 가끔 "has-a"관계가 더 맞지만 동적으로 그 object을 생성해야 하는 경우가 있었고, 그럴때는 pointer를 사용해야 해서 모양새가 association인것과 같은 경우가 있었는데, 이런 경우에 aggregation을 사용해야 한다. 그래서 Aggregation은 composition과 같이 "has-a"관계이지만 동적으로 할당해야 해서 pointer를 사용해야 하는 경우 정의된다고 할 수 있는것 같다.

그렇다면 두 경우 모두 pointer 형을 사용하는 association과 aggregation의 차이는 다음과 같이 말할 수 있다. Association은 클래스 내에서 포인터를 통해서 다른 object로의 access를 가능하게 해주지만 이 관계를 성립해주는 곳은 두 클래스의 scope 밖이다. 반면 aggregation은 한 object로의 access를 가능하게 해주는 곳이 그 class 내이다. 즉, 동적으로 할당되는 위치도 그 class의 scope 내이다.

class A_composition
{
private:
   B pb;
public:
   A_composition();
   ~A_composition();
};

class A_aggregation
{
private:
    B* pb;
public:
    A_aggregation();
    ~A_aggregation();
};

class A_association
{
private:
    B* pb;
public:
    A_association();
    ~A_association();
    void AknowsB(B* b);
};

class B
{
public:
    B();
    ~B();
};


위와 같이 네 class가 있다면...
Composition은 class A_composition과 같이 그 class 내에서 다른 class object를 멤버를 가지고 있는것 만으로 성립되는 관계이고,

Aggregation은 class A_aggregation처럼 class 내에 class B의 포인터형을 member로 가지고 있으며 그 pointer를 통해서 class B의 object로의 액세스를 가능하게 해준다. Class B object는 class A_aggregation에서 동적으로 할당되어 사실상 class A_aggregation이 class B object를 가지고 있는 형태가 되어야 하고, 꼭class A_aggregation의 scope내에서 동적으로 할당되어야 한다.
예를 들면...
A_aggregation::A_aggregation()과 같은 constructor나 A_aggregation의 method 내애서
pb = new B()

와 같은 구문을 사용해서 동적으로 할당되어야 한다.

반면 Association은 Aggregation처럼 class 내에 다른 class object로의 pointer를 member로 가지고 있지만, 그 object가 생성되는 위치는 Aggregation의 예와는 다르다. Association은 class A_Association처럼 memeber로 class B의 pointer형을 member로 가지고 있지만, Aggregation의 예에서와는 다르게 class B의 object는 A_association의 scope 밖에서 생성되어야지만 class A_association과 class B와의 관계가 association이라고 할 수 있다.
그래서 aggregation에서의 예와는 다르게

A_association a;
B b;
a.AknowsB(&B);


이런식으로 A_association과 b가 서로의 scope가 아닌 곳에서(위의 예에서 처럼 같은 scope에서 생성될 필요는 없다) 생성되고, A_association의 AknowsB와 같은 method를 통해서 association의 관계를 성립시켜주어야 한다.

이것이 내가 이해한 Composition, Aggregation, 그리고 Association의 차이다...
Posted by Dansoonie
It's been a while since I have learned C++ from school. The last time I heard about circular dependency in C++ was from my sophomore year in college. Yesterday, I was having trouble making circular dependency to get working. I decided to post about how I solved the problems I had considering that circular dependency isn't a situation you encounter very often. I usually get rusty on things I don't do often. Hopefully, many people are like me and some may benefit from this post sometime later.


While at work designing an application, I encountered a situation where two classes had attributes of their own referring to another class in the following manner.
사용자 삽입 이미지
I recognized that this resulted in a circular dependency and included a forward declaration in the header file of each class for the class that it was referring to. So the header file for each class resulted in the following.
 
// A.h
class B;   // forward declaration for class B
class A
{
    private:
       B* pB
    public:
       ...
};

// B.h
class A;    // forward declaration for class A
class B
{
    private:
       A a;
    public:
       ...
};
However, I got a compile error indicating that class A and B were not defined. It was weird at first because I thought I got my circular dependency problem solved. I had no idea how to get around the compile error. My solution to this was to create another class to use it as a mediator for the establishing an associative relationship between class A and B. My new design was like the following.
사용자 삽입 이미지
I was stupid enough to think that this new design will avoid the circular dependency relationship. But after another build of my application, I figured that this also results in a circular dependency. If you look carefully at the #include statements in each header file for class A, B, and C,
    - A.h includes C.h
    - C.h includes B.h
    - B.h includes A.h
, but then B must compile A.cpp and A cannot be compiled because C and B has not been compiled. Therefore, class A is not defined and the circular dependency prevents the code to be compiled in spite of the forward declarations.

At this point, I realized that class A does not require C.cpp to be compiled. This is because that  class A refers to class C with a pointer. As you all know, pointers are usually a 4 byte (32 bit) integer and as long as the type of the pointer is specified, the code compiles. From what I have just realized, I decided to change my design like the following.
사용자 삽입 이미지
I could have gotten rid of class C but I kept it for another good reason (design issue in my application). As I changed all my inter class relationship into association, the code compiled as I expected and also worked fine.


The point I would like to make here is that it is important that you know that circular dependency only works only when classes are associated with each other based on pointers.

 Was this so obvious?
Posted by Dansoonie