Java設計模式-類之間的關係

每節課都認真聽、發表於2020-11-05

類之間的關係

       在軟體系統中類並不是孤立存在的,類與類之間存在各種關係,對於不同型別的關係,UML提供了不同的表示方法。

關聯關係

       關聯(Association)關係是類與類之間最常見的一種關係,它是一種結構化關係,用於表示一類物件與另一類物件之間有聯絡,如汽車和輪胎、師傅和徒弟、班級和學生等。在UML類圖中用實現連線有關聯關係的物件所對應的類,在使用Java、C#和C++等程式語言實現關聯關係時,通常將一個類的物件作為另一個類的成員變數。在使用類圖表示關聯關係時可以在關聯線上標註角色名,一般使用一個表示兩者之間關係的動詞或者名詞表示角色名(有時該名詞為例項物件名),關係的兩端代表兩種不同的角色,因此一個關聯關係中可以包含兩個角色名,角色名不是必須的,可以根據需要新增,其目的是是類之間的關係更加明確。
       例如在一個登入介面類LoginForm中包含一個JButton型別的註冊按鈕loginButton,它們之間可以表示為關聯關係,程式碼實現時可以在LoginForm中定義一個名為loginButton的屬性物件,其型別是JButton。

在這裡插入圖片描述
Java程式碼片段:

public class LoginForm {
	private JButton loginButton;//定義為成員變數
	...
}

public class JButton {
	...
}

1.雙向關聯
       在預設情況下關聯是雙向的。例如過客(Customer)購買商品(Product)並擁有商品,反之,賣出的商品總有某個顧客與之相關聯。因此,Customer類和Product類之間具有雙向關聯關係。

在這裡插入圖片描述
Java程式碼片段:

public class Customer {
	private Product[] products;
	...
}

public class Product {
	private Customer customer;
	...
}

2.單向關聯
       類的關聯關係也可以是單向的,單向關聯用帶箭頭的實線表示。例如顧客(Customer)擁有地址(Address),則Customer類與地址Address類具有單向關聯關係。

在這裡插入圖片描述
Java程式碼片段:

public class Customer {
	private Address address;
	...
}

public class Address {
	...
}

3.自關聯
       在系統中可能會存在一些類的屬性物件型別為該類本身,這種特殊的關聯關係稱為自關聯。例如一個結點類(Node)的成員又是結點Node型別的物件。
在這裡插入圖片描述
Java程式碼片段:

public class Node {
	private Node subNode;
	...
}

4.多重性關聯
       多重性關聯關係又稱為重數性(Multiplicity)關聯關係,表示兩個關聯物件在數量上的對應關係。在UML中,物件之間的多重性可以直接在關聯直線上用一個數字或一個數字範圍表示。
物件之間可以存在多種多重性關聯關係,常見的多重性表示方式如表所示。

表示方式多重性說明
1. .1表示另一個類的一個物件只與該類的一個物件有關係
0. .*表示另一個類的一個物件與該類的零個或多個物件有關係
1. .*表示另一個類的一個物件與該類的一個或多個物件有關係
0. .1表示另一個類的一個物件沒有或只與該類的一個物件有關係
m. .n表示另一個類的一個物件與該類最少有m、最多有n個物件有關係(m<=n)

       例如一個介面(Form)可以擁有零個或多個按鈕(Button),但是一個按鈕只能屬於一個介面,因此一個Form類的物件可以與零個多個Button類的物件相關聯,但一個Button類的物件只能與一個Form類的物件關聯。
在這裡插入圖片描述
Java程式碼片段:

public class Form {
	private Button[] buttons;//定義一個集合物件
	...
}

public class Button {
	...
}

5.聚合關係
       聚合(Aggregation)關係表示整體與部分的關係。在聚合關係中,成員物件是整體物件的一部分,但是成員物件可以脫離整體物件獨立存在。在UML中,聚合關係用帶空心菱形的直線表示。例如汽車發動機(Engine)是汽車(Car)的組成部分,但是汽車發動機可以獨立存在,因此汽車和發動機是聚合關係。
在這裡插入圖片描述
Java程式碼片段:
       在程式碼實現聚合關係時,成員物件通常作為構造方法、Setter方法和業務方法的引數注入到整體物件中。

public class Car {
	private Engine engine;

	//構造注入
	public Car(Engine engine) {
		this.engine = engine;
	}

	//設值注入
	public void setEngine(Engine engine) {
		this.engine = engine;
	}
	...
}

public class Engine {
	...
}

6.組合關係
       組合(Composition)關係也表示類之間整體和部分的關係,但是在組合關係中整體物件可以控制成員物件的生命週期,一旦整體物件不存在,成員物件也將不存在,成員物件和整體物件之間具有同生共死的關係。在UML中,組合關係用帶實心菱形的直線表示。例如人的頭(Head)與嘴巴(Mouth),嘴巴是頭的組成部分之一,而且如果頭沒了,嘴巴也就沒了,因此頭和嘴巴是組合關係。
在這裡插入圖片描述
Java程式碼片段:
       在程式碼實現組合關係時,通常在整體類的構造方法中直接例項化成員類。

public class Head {
	private Mouth mouth;
	
	public Head() {
		mouth = new Mouth();//例項化成員類
	}
	...
}

public class Mouth() {
	...
}

依賴關係

       依賴(Dependency)關係是一種使用關係,特定事物的改變有可能會影響到使用該事物的其他事物,在需要表示一個事物使用另一個事物時使用依賴關係。在大多數情況下,依賴關係體現在某個類的方法使用另一個類的物件作為引數。在UML中,依賴關係用帶箭頭的虛線表示,由依賴的一方指向被依賴的一方。例如駕駛員開車,在Driver類的drive()方法中將Car型別的物件car作為一個引數傳遞,以便在drive()方法中能夠呼叫car的move()方法,駕駛員的drive()方法依賴車的move()方法,因此類Driver依賴類Car。

在這裡插入圖片描述
       在系統實現階段,依賴關係通常通過3種方式來實現:第一種(也是最常見的一種方式)如圖所示,將一個類的物件作為另一個類中方法的引數;第二種方法是在一個類中的方法中將另一個類的物件作為其區域性變數;第三種方式是在一個類的方法中呼叫另一個類的靜態方法。
圖所對應的Java程式碼片段如下:

public class Driver {
	public void drive(Car car) {
		car.move();
	}
	...
}

public class Car {
	public void move() {
		...
	}
	...
}

泛化關係

       泛化(Generalization)關係也就是繼承關係,用於描述父類和子類之間的關係,父類又稱作基類或超類,子類又稱作派生類。在UML中,泛化關係用帶空心三角形的直線來表示。在程式碼實現時,使用物件導向的繼承機制來實現泛化關係,在Java語言中使用extends關鍵字來實現。例如Student類和Teacher類都是Person類的子類,Student類和Teacher類繼承了Person類的屬性和方法,Person類的屬性包含姓名(name)和年齡(age),每一個Student類和Teacher類也都具有這兩個屬性,另外Student類增加了屬性學號(studentNo),Teacher類增加了屬性教師編號(teacherNo),Person類的方法包括行走move()和說話say(),Student類和Teacher類繼承了這兩個方法,而且Student類還新增了方法study(),Teacher類還新增了方法teach()。

在這裡插入圖片描述
Java程式碼片段:

//父類
public class Person {
	protected String name;
	protected int age;

	public void move() {
		...
	}

	public void say() {
		...
	}
}

//子類
public class Student extends Person {
	private String studentNo;

	public void study() {
		...
	}
}

//子類
public class Teacher extends Person {
	private String teacherNo;

	public void teach() {
		...
	}
}

介面與實現關係

       在很多物件導向語言中都引入了介面的概念,例如Java、C#等,在介面中通常沒有屬性,而且所有的操作都是抽象的,只有操作的宣告,沒有操作的實現。在UML中用與類的表示法類似的方式表示介面。
       介面之間也可以有與類之間關係類似的繼承關係和依賴關係,但是介面和類之間還存在一種實現(Realization)關係,在這種關係中類實現了介面,類中的操作實現了介面所宣告的操作。在UML中,類與介面之間的實現關係用帶空心三角形的虛線來表示。例如定義一個交通工具介面Vehicle,包含一個抽象操作move(),在類Ship和類Car中都實現了該move()操作,不過具體的實現細節將會不一樣。
在這裡插入圖片描述
Java程式碼片段:
       實現關係在用程式碼實現時不同的面嚮物件語言也提供了不同的方法,在Java語言中使用implements關鍵字來實現。

public interface Vehicle {
	public void move();
}

public class Ship implements Vehicle {
	public void move(){
		...
	}
}

public class Car implements Vehicle {
	public void move() {
		...
	}
}

相關文章