电竞比分网-中国电竞赛事及体育赛事平台

分享

UML中類之間的關(guān)系

 昵稱22369024 2015-05-03
類之間可能存在以下幾種關(guān)系:關(guān)聯(lián)(association)、依賴(dependency)、聚合(Aggregation,也有的稱聚集)、組合(Composition)、泛化(generalization,也有的稱繼承)、實現(xiàn)(Realization)。
關(guān)聯(lián)是指兩個類之間存在某種特定的對應(yīng)關(guān)系,例如客戶和訂單,一個訂單只能屬于某個客戶,一個客戶可能會有多張訂單。根據(jù)方向,分為單向和雙向。根據(jù)對應(yīng)的數(shù)量分為一對一、一對多、多對多等。對應(yīng)的UML圖如下所示:
UML中類之間的幾種關(guān)系
    關(guān)聯(lián)關(guān)系用實線+箭頭表示。上圖顯示Customer和Order是雙向一對多關(guān)聯(lián)關(guān)系。對應(yīng)的Java代碼如下所示:
 class Customer {
  private Integer id;
  private String name;
  private Set<Order> orders;
  public Set<Order> getOrders() {
   return orders;
  }
  public void setOrders(Set<Order> orders) {
   this.orders = orders;
  }
 }
 class Order {
  private Integer id;
  private float money;
  private Customer customer;
  public Customer getCustomer() {
   return customer;
  }
  public void setCustomer(Customer customer) {
   this.customer = customer;
  }
 }
Customer和Order是雙向一對多關(guān)聯(lián)關(guān)系,那么在Customer中應(yīng)該有Order的集合,在Order中應(yīng)該Customer的屬性。
 
依賴指的是類之間的調(diào)用關(guān)系。類A訪問類B的屬性或方法,或者類A負(fù)責(zé)實例化類B,那么就說類A依賴于類B。和關(guān)聯(lián)關(guān)系不同的是,無需在類A中定義類B類型的屬性。例如自行車和打氣筒,自行車通過打氣筒來充氣,那么就需要調(diào)用打氣筒的充氣方法。對應(yīng)的UML圖如下所示:
UML中類之間的幾種關(guān)系
    依賴關(guān)系用虛線+箭頭表示。上圖顯示Bicycle和Pump是依賴關(guān)系,Bicycle依賴于Pump。對應(yīng)的Java代碼如下所示:
 class Bicycle {
  public void expand(Pump pump) {
   pump.blow();
  }
 }
 class Pump {
  public void blow() {
   System.out.println("正在充氣......");
  }
 }
打氣筒并不屬于某個特定的自行車,一個打氣筒可以為多個自行車提供充氣的服務(wù)。在Bicycle中不需要定義Pump類型的屬性,而是將傳遞了一個Pump類型的參數(shù)到Bicycle的方法中。
 
聚合是整體與部分之間的關(guān)系。例如計算機和主板,計算機是一個整體,主板是其中的一部分,主板、顯卡、顯示器等部件組成了計算機。對應(yīng)的UML圖如下所示:
 UML中類之間的幾種關(guān)系
    聚合使用空心菱形+實線表示。上圖顯示Computer是由MainBoard和DisplayCard等組成的。對應(yīng)的Java代碼如下所示:
 class Computer {
  private MainBoard mainBoard;
  private DisplayCard displayCard;
  
  public void on() {
   System.out.println("開啟計算機......");
  }
  public void close() {
   System.out.println("關(guān)閉計算機......");
  }
  public void run() {
   System.out.println("計算機正在運行......");
  }
 }
 class MainBoard {
  public void control() {
   System.out.println("控制計算機......");
  }
 }
 class DisplayCard {
  public void display() {
   System.out.println("計算顯示數(shù)據(jù)......");
  }
 }
計算機由主板、顯卡等部件組成,所以在Computer中定義了MainBoard和DisplayCard類型的屬性。
聚合中類之間可以獨立出來,比如一塊主板可以狀態(tài)A計算機上,也可以裝在B計算機上。也就是說這塊主板離開A計算機之后仍然是有意義的。
 
組合中的類也是整體與部分的關(guān)系,與聚合不同的而是,其中的類不能對立出來。例如一個人由頭、手、腿和軀干等組成,如果這個頭離開了這個人,那么這個頭就沒有任何意義了。對應(yīng)的UML圖如下所示:
UML中類之間的幾種關(guān)系
組合使用實心菱形和實線表示。上圖表示People是由Head、Hand、Leg等組成。對應(yīng)的Java代碼如下所示:
 class People {
  private Head head;
  private Hand hand;
  private Leg leg;
  public void think() {
   head.think();
  }
  public void holdThing() {
   hand.holdThing();
  }
  public void walk() {
   leg.walk();
  }
 }
 class Head {
  public void think() {
   System.out.println("思考......");
  }
 }
 class Hand {
  public void holdThing() {
   System.out.println("拿東西......");
  }
 }
 class Leg {
  public void walk() {
   System.out.println("走路......");
  }
 }
People和Head、Hand、Leg是不可分割的,Head、Hand、Leg離開了People沒有任何實際意義。在People中定義了Head、Hand、Leg類型的屬性,組合也可以看成是聚合的一種特殊形式。
聚合和組合的代碼幾乎相同,單憑代碼是無法區(qū)分兩個類之間是聚合還是組合的關(guān)系的。所以就需要結(jié)合實際的業(yè)務(wù)環(huán)境來區(qū)分。例如汽車和輪胎,車主買了一輛汽車,上邊肯定是由輪胎的,在這個業(yè)務(wù)中,輪胎和汽車是組合關(guān)系,它們分開就沒有實際意義了。在汽車修理店,汽車可以更換輪胎,所以在汽修店的業(yè)務(wù)環(huán)境中,汽車和輪胎就是聚合的關(guān)系,輪胎離開汽車是有業(yè)務(wù)意義的。
 
泛化比較好理解,就是兩個類之間具有繼承關(guān)系。例如人和學(xué)生,學(xué)生繼承了人,除過具有人的一般的屬性和方法之外,他還要有學(xué)習(xí)的方法。對應(yīng)的UML圖如下所示:
UML中類之間的幾種關(guān)系
    泛化用空心三角形+實線表示。上圖表示Student繼承People。對應(yīng)的Java代碼如下所示:
 class People {
  protected String name;
  protected String sex;
  protected Date birthday;
  public void eat() {
   System.out.println(name + "正在吃飯......");
  }
  public void drink() {
   System.out.println(name + "正在喝水......");
  }
  public void sleep() {
   System.out.println(name + "正在休息......");
  }
 }
 class Student extends People {
  public void study() {
   System.out.println(name + "正在學(xué)習(xí)......");
  }
 }
Student繼承自People,并且多了一個study的方法。
 
實現(xiàn)即一個類實現(xiàn)了某個接口。對應(yīng)的UML圖如下所示:
UML中類之間的幾種關(guān)系
    實現(xiàn)用三角形箭頭和虛線表示。上圖表示類CarDriver和PlaneDriver都實現(xiàn)了Driver接口。對應(yīng)的Java代碼如下所示:
public interface Driver {
 void drive();
}
 class CarDriver implements Driver {
  public void drive() {
   System.out.println("駕駛汽車......");
  }
 }
 class PlaneDriver implements Driver {
  public void drive() {
   System.out.println("駕駛飛機......");
  }
 }
 
值得注意的是,關(guān)聯(lián)、依賴、聚合、組合的關(guān)系很容易搞混。當(dāng)對象A和對象B之間存在關(guān)聯(lián)、依賴、聚合或者組合關(guān)系時,對象A都有可能調(diào)用對象B的方法。這是它們的相同之處。另外它們還有自己的特征。
對于兩個相對獨立的對象A和B,當(dāng)一個對象A的實例與B的實例存在固定的對應(yīng)關(guān)系時,這兩個對象之間為關(guān)聯(lián)關(guān)系。代碼中表現(xiàn)為在A中定義了B類型的屬性。
對于兩個相對獨立的對象A和B,當(dāng)一個對象A負(fù)責(zé)構(gòu)造對象B的實例,或者調(diào)用對象B提供的服務(wù)時,這兩個對象之間主要體現(xiàn)為依賴關(guān)系。代碼中的表現(xiàn)即將B類型的參數(shù)傳入A的方法中,而不是在A中定義B類型的屬性。
聚合、組合與關(guān)聯(lián)在代碼中并沒有明顯的區(qū)別,主要看實際的業(yè)務(wù)環(huán)境,根據(jù)代碼所處的實際業(yè)務(wù)環(huán)境來判斷它們之間的關(guān)系。同樣的兩個類,處在不同的業(yè)務(wù)環(huán)境中,可能它們的關(guān)系也不相同。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多