你是我的玫瑰-類關係闡微

        世界是普遍聯繫的,因此程序世界中的類,也不可能是孤立的。UML爲我們定義了它們之間的關係,就是:依賴、關聯、聚合、組合還有泛化。

       泛化關係比較好理解,就是表示類之間的繼承關係。容易混淆的是依賴、關聯、聚合和組合的關係。這裏做一些甄別:

       1、 依賴和關聯的顛倒顛

       在網上查找了一下依賴和關聯的區別,有說“關聯本身即是一種依賴”,亦有說“依賴是一種弱關聯”,其實說來說去是一檔子事。依賴和關聯都是說一個類用到了另一個類。其區別在於一個是使用,一個是擁有。

      依賴:具有某種偶然性。比如說我要過河,沒有橋怎麼辦,我就去借來一條小船渡過去。我與小船的關係僅僅是使用(借用)的關係。表現在代碼上,爲依賴的類的某個方法以被依賴的類作爲其參數。或者是class A 的某個方法創造了 class B 的實例抑或對class B靜態方法的調用。如果A依賴於B,那意味着B的變化可能要求A也發生變化;

       這是uml圖表示的依賴關係:
       
代碼表現:

1public class Person{    
2    /**//** 划船 */   
3    public void oarage (Boat boat){    
4        boat.oarage();    
5 }
    
6}
 
7

 

關聯:有名的客戶和訂單的關係以及公司和員工的關係,都是關聯關係。還有就是我和我的單車的例子,他們都是一種“擁有”的關係。表現在代碼上,就是一個類包含另一個類的實例,通常表現爲被關聯類以類屬性的形式出現在關聯類的類定義中,也可以表現爲關聯類引用了一個類型爲被關聯類的全局變量。關聯可以使單向的,也可以使雙向的。

從網上找到的公司和員工的UML圖和代碼 :


公司和員工的關聯關係
 1public class Company{    
 2    private Employee employee;    
 3    public Employee getEmployee(){    
 4        return employee;    
 5    }
    
 6    public void setEmployee(Employee employee){    
 7        this.employee=employee;    
 8    }
    
 9    //公司運作    
10    public void run(){    
11        employee.startWorking();    
12    }
    
13}
  
14

 

可見依賴於與關聯亦有動靜之別,關聯的類靜態地引用了被關聯類的實例變量,而依賴的偶然性也正說明了它的動態性。

      2、 聚合與組合同出而異體

      聚合與組合其實都是關聯的特例,都是整體和部分的關係。他們的區別在於聚合的兩個對象之間是可分離的,他們具有各自的生命週期。而組合往往表現爲一種脣齒相依的關係。

聚合:一種容納或曰包含的關係,如同機場和飛機,汽車和輪胎的關係。其實仔細想想,前面的公司和員工的關係也有聚合的味道在裏面。

組合:也可稱之爲強聚合,整體和部分是不可分的,整體的生命週期結束時也就是部分的生命週期到頭時。很有名的就是桌子和桌子腿的關係。

      聚合的UML

組合的UML圖:




 

然而,聚合與組合的代碼表現形式是一樣的,都可以表現爲以下的形式,它們僅僅具有語義上的區別。

網上找到的電腦和CPU的關係的代碼表現:

 1public class Computer{    
 2    private CPU cpu;    
 3    public CPU getCPU(){    
 4        return cpu;    
 5    }
    
 6    public void setCPU(CPU cpu){    
 7        this.cpu=cpu;    
 8    }
    
 9    //開啓電腦    
10    public void start(){    
11        //cpu運作    
12        cpu.run();    
13    }
    
14}
  
15

 

   結語:

      一般情況下,當某個類被當作參數傳遞並且被當作結果返回的時候,或者被當作某個方法內的臨時變量使用的時候,可以運用依賴關係,使用關聯來表示一個擁有關係,而不是整體-部分關係。使用聚合來表示一個動態的整體-部分關係,而是用組合來表示一個靜態的整體-部分關係。但是需要指出的是,所謂“關係”只是在某個問題域纔有效,離開了這個問題域,可能這些關係就不成立了,例如之前我和小船的關係,可能在某個問題域中,我是船伕,我的工作就是駕着小船在河上擺渡,那我和小船的關係就上升爲關聯關係了。試想一下,武俠小說中的那些劍仙們,修煉到人劍合一的境地,劍在人在,劍亡人亡,那它們之間的關係就似乎與組合關係類似了。又如在關心汽車的領域裏,輪胎是一定要組合在汽車類中的,因爲它離開了汽車就沒有意義了。但是在賣輪胎的店鋪業務裏,就算輪胎離開了汽車,它也是有意義的,這就可以用聚合了。這說明關係是在特定的問題域中的“關係”,會隨着問題域的遷移而改變的。最後順便問一句:老公和老婆的關係是依賴還是關聯呢?一笑……

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章