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