1. 設計模式的重要性
1.1?設計模式解決的是在軟件過程中如何來實現具體的軟件功能。實現同一個功能的方法有很多,哪個設計容易擴展,容易復用,松耦合,可維護?設計模式指導我們找到最優方案。
1.2?設計中往往會存在設計缺陷,這些缺陷包括:
僵化性:難以對軟件進行改動,即使在功能上來看是很小的改動
脆弱性:在進行很小的改動時,可能導致很多地方出現問題
頑固性:要把系統中某些通用的功能分離出來的努力和風險非常巨大
粘滯性:當面臨改動時,改動的方案有很多,一些會保持設計,一些會破壞設計,當采用保持設計的方法比用破壞設計的方法更難應付變化時,說明原設計具有較高的粘滯性
晦澀性:模塊難以理解
不必要的重復:代碼不能復用,往往通過Copy-Paste來實現相似功能
不必要的復雜性:設計中包含了沒有用的成分,往往是過度設計導致的
1.3?如果你覺得在開發過程中發現以上問題(缺陷),那么就需要使用設計模式來改善最初設計,即重構原有的設計。如果你是最初的設計者,那么也需要應用設計模式來找到一個最優方案。設計模式不是編程語言,它修煉的是程序員的內功。因此,對于一個開發者來說,學習設計模式是非常必要的。
2. 對于初學者來說,必要的知識準備還是必須的,沒有這些基礎就很難將這些理解透徹。
2.1?面向對象基本知識
設計模式是面向對象編程的設計指導,因此學習設計模式前先要理解什么是面向對象,這里只簡單列出了面向對象的主要概念,要是初學者的話還得查閱相關資料;對已經了解的老手來說,權當復習和梳理一下吧。
2.1.1 面向對象三大特征:封裝、繼承、多態
2.1.2 類與實例
2.1.3 構造(析構)方法
2.1.4 重載
2.1.5 訪問修飾符
2.1.6 屬性/字段/方法
2.1.7 抽象類
2.1.8 接口
2.2?UML類圖
在學習設計模式時,通常接觸到的只有類圖,因此讀懂UML類圖對理解模式來說有很大幫助。下面來介紹UML類圖中的關系
2.2.1 依賴關系(Dependency),用虛線加箭頭表示。如上圖動物(Animal)依賴空氣(Air)。表示依賴關系的代碼有以下幾種
1)作為參數
public class Air{public void GetOxygen() { Console.WriteLine("Get oxygen from air."); } } public abstract class Animal { /// <summary> /// 動物依賴空氣才能呼吸,作為參數傳入 /// </summary> /// <param name="air"></param> public void Breathe(Air air) { air.GetOxygen(); } }
2)在方法內部定義
/// <summary>/// 動物依賴空氣才能呼吸,在方法內部實例化新對象/// </summary> public void Breathe() { Air air = new Air(); air.GetOxygen(); }
3)靜態方法調用
/// <summary>/// 在方法中調用靜態方法/// </summary> public void Test() { ClassName.UseStaticMethode(); }
2.2.2 繼承關系(Inherit),用實線加空心箭頭表示,如上圖鷹(Eagle)繼承自動物(Animal)
/// <summary>/// 鷹繼承自Animal/// </summary> public class Eagle : Animal { }
2.2.3 實現關系(Realize),用虛線加空心箭頭表示,如上圖鷹(Eagle)實現了飛行能力(IFlyAble)
/// <summary>/// 鷹繼承自Animal/// </summary> public class Eagle : Animal, IFlyAble { //實現IFlyAble接口中定義的方法 public void Fly() { Console.WriteLine("老鷹可以飛翔。"); } }
2.2.4 組合關系,講組合關系之前不得不談關聯關系與聚合關系
1)關聯關系(Association):對于兩個相對獨立的對象,當一個對象實例與另一個對象的一些特定實例存在固定的對應關系時,這兩個對象之間的關系為關聯關系。例如:公司與員工的關系
代碼表現,通過實例字段或屬性來實現
public class Emplolyee{public string Name{ get; set; }}public class Company { /// <summary> /// 一個公司可以有多個員工 /// </summary> private Emplolyee[] employees; }
2) 聚合關系(Aggregate): 是關聯關系的一種,是一種較強的關聯關系,強調整體與部分之間的關系。例如:電腦與顯示器的關系,就是整體與部分的關系,即聚合關系
代碼表現,也是通過實例字段或屬性來實現
public class Displayer{/// <summary>/// 顯示器型號 /// </summary> public string Model { get; set; } } public class Computer { /// <summary> /// 通過字段表示聚合關系 /// </summary> private Displayer displayer; }
3)組合關系,組合關系是聚合的一種特殊形式,表示一個所有物實例不能同時被兩個所有物所擁有。如上例:鷹擁有一對翅膀,它的翅膀不能同時屬于別的鷹。
代碼表現,也是通過實例字段或屬性來實現
public class Wing{}/// <summary>/// 鷹繼承自Animal /// </summary> public class Eagle : Animal, IFlyAble { private Wing leftWing; private Wing rightWing; public Eagle() { // 在構造函數中實例化翅膀,防止翅膀被改變 leftWing = new Wing(); rightWing = new Wing(); } public void Fly() { Console.WriteLine("老鷹可以飛翔。"); } }
關聯關系與聚合關系的區別: 關聯關系所涉及的兩個對象是處在同一個層次上的,比如程序員和計算機的關系就是一種關聯關系,而不是聚合關系,因為程序員不是由計算機組成的。聚合關系涉 及的兩個對象處于不平等的層次上,一個代表整體,一個代表部分。如計算機與顯示器的關系就是聚集關系,因為顯示器是計算機的一部分。
聚合關系與組合關系的區別:聚合關系中處于被持有的對象,可以被別的對象所持有。如多態計算機可以共享同一個顯示器。組合關系中被持有的對象只能被一個對象引用,不能共享給其它對象;而且被持有的對象的生命周期也由所有者控制,當所有者析構了,其所有物必須隨著它一起析構。