(原創) association,aggregation,composition有什麼差別? (OO) (UML) (C/C++)

class之間有三種關係,inheritance,implementation和association。inheritance和implementation在C++、C#、Java都有直接支援,所以不難懂,但association,aggregation和composition在語言並沒有知接支援,到底三者有什麼差別呢?

首先看association,下圖是個典型的assoication class diagram。



association的表示法是實線加上箭頭,有兩個重點,navigability和multiplicity,navigability就是箭頭指的方向,指別的class的,表示負責維護association關係,在此class中有data member存著被指class的reference(pointer),multiplicity則是上面的數字,離自己class比較遠的,表示對方class和自己class之間的關係,如上圖,1個School可以有多個Student,而1個Student只能有一個School,而一個Student可以選1到6個Course,1個Course可被1到多個Student選。

association常見的問題是,到底箭頭該怎麼指才對?一般來說,若是一對多的關係,是由一指向多,因為通堂一個class會有個array或vector儲存多個物件,但這並非絕對,只能說通常如此,如上圖的Student對Course是一對多,且Course對Student也是一對多,但他選擇了由Course負責association關係,所以完全看設計需要,實務上,建議如UML for Java Programmer中文版p.3-15那樣,加上stereotype,詳細的敘述是屬於哪一種association,將來我會再專文介紹。

若以C++表示,association的程式碼如下
1class A {
2  private:
3    B* itsB;
4}
;

再來看aggregation

aggregation的表示法由空diamond和箭頭表示(選的這張圖是比較舊的UML格式,所以沒有箭頭),空diamond表示whole,箭頭表示part。若以英文表示,就是has a的關係,上圖是典型一對多的表示法。

若以C++表示,aggregation的程式碼如下
1class Node {
2  private:
3    vector<Node*> itsNodes;
4}
;

最後是composition,表示法與aggregation的差異在於變成實diamond,其他完全一樣,跟aggregation在意義的差異在於composition強調『同生共死』,當System物件死亡時,Component物件也要跟著死亡,但aggregation是『生死有命』,當System物件死亡時,Component物件並不特別去處理。

若以C++表示,composition的程式碼如下
1class Car {
2  public:
3    virtual ~Car() {delete itsCarb;}
4  private:
5    Carburetor* itsCarb
6}
;

由以上程式可知,composition須由destructor去處理,而aggregation則不必。

在C#、Java這類有garbage collection的語言,composition幾乎不會用到,但在C++,只要用到pointer,就得自己去delete,所以在composition對於C++就很重要。


Reference
http://www.visualcase.com/kbase/associations.htm
http://ootips.org/uml-hasa.html
http://www.tomjewett.com/dbdesign/dbdesign.php?page=aggregate.php
UML for Java Programmer中文版 p.3-11 ~ p.3-13
UML Distilled 2nd中文版

posted on 2007-02-20 16:30  真 OO无双  阅读(...)  评论(...编辑  收藏

导航

统计