一、當你的項目發現有如下問題之一時,就需要考慮重構代碼,可能會有某種模式適合。
1、代碼無法進行單元測試。
2、需求的變動總是導致代碼的變動。
3、有重復代碼的存在。
4、繼承層次過多。
5、隱藏的依賴過多。
二、UML表示法
1、UML類圖

"+"代表Public,“#”代表protected,“-”代表private,即
代表變量 public string Prol;
代表方法 public void Method1(){ }
2、UML序列圖

序列圖描述系統的動態交互過程,在序列圖中,垂直虛線叫做“生命線”,代表一個對象的生存周期,每一個箭頭代表一個調用,
在生命線上若有空心條,代表調用的激活周期,成為激活條。
三、系統的可維護性包括如下幾個方面:
1、可擴展性:有了新的需求,新的性能可以容易地添加到系統中,並且不影響現有的性能,也不會帶來新的缺陷。
2、可修改性:系統某一部分的代碼需要修改時不會破壞系統現有的結構,也不會影響到其他部分。
3、可替換性:可以將系統中的某些類替換為相同接口的其他類,並且系統不受影響。
四、“開-閉”原則:
指軟件實體應當對擴展開放,對修改關閉,即軟件實體應該在不修改的前提下擴展。
五、封裝變化
程序中任何可能發生變化的部分都可以封裝為對象,包括命令、事件、屬性、算法、形態等。
封裝變化是實現“開-閉”原則的重要手段,也是在設計中發現對象的重要途徑。
因此在分析需求時,一定要注意什么是變的,什么是可能發生變化的,以及這些可能的變化會對封裝帶來的影響。
六、面向接口編程的優勢:
1、降低程序各部分之間的耦合性,使程序模塊互換成為可能。這樣客戶無需知道自己使用的對象類型,只要對象有客戶所期望的接口即可。
並且對象也不需要知道對象是如何實現的,只要知道定義接口的抽象類。
2、使軟件各部分便於單元測試,通過編制與接口一致的模擬類(Mock),可以很容易地實現軟件各部分的單元測試。從而提高軟件的可靠性,降低錯誤率。
3、易於實現軟件模塊的互換,軟件升級時可以只部署發生變化的部分,而不會影響其他部分。
七、繼承的缺點
1、繼承在編譯時定義,無法在運行時改變,無法在運行時動態的選擇繼承或者不繼承某一個類。
2、繼承對子類暴露了父類的實現細節,從而破壞了封裝性。
3、子類和父類耦合性非常強,一旦父類發生變化,必然導致子類也發生變化。
八、設計模式解決的問題
| 問題 | 設計模式 | 描述 |
| 通過顯示指定類創建對象 | 抽象工廠模式、工廠方法模式、原型模式 | 在實例化時,間接創建對象 |
| 緊耦合 | 抽象工廠模式、命令模式、外觀模式、中介者模式、觀察者模式和職責鏈模式等 | 類之間需松耦合 |
| 通過生成子類擴展功能 | 橋接模式、職責鏈模式、組合模式、裝飾模式、觀察者模式、策略模式等 | 通過生成子類來擴展功能會產生很多問題,如引起子類數量大量增加和類層次的增加。 通過對象組合技術實現功能擴展是更好的選擇 |
| 對對象表示或實現的依賴 | 抽象工廠模式、橋接模式、備忘錄模式、代理模式等 | 對客戶隱藏對象如何表示、保存、定位或實現等。 |
| 不能方便地修改類 | 適配器模式、裝飾模式、訪問者模式 | |
| 對算法的依賴 | 生成器模式、迭代器模式、策略模式、模板模式、訪問者模式 | 算法實現的目的是不變的,但算法本身卻不是一成不變的 |
| 對軟硬件環境的依賴 | 抽象工廠模式、橋接模式等 |
九、設計模式所用到的接口和類(.NET)
| 接口/類 | 設計模式 | 描述 |
| ICloneable | 原型模式 | 這個接口支持克隆,即創建與當前實例相同的實例,方法為Clone() |
| IEnumerable/IEnumerator | 迭代子模式 | 公開枚舉數支持在集合上進行簡單迭代 |
| MenuCommand類/IMenuCommandService | 命令模式 | 提供了對自定義組件行為的基類 |
| CollectionBase類 | 組合模式、命令模式、享元模式、觀察者模式 | CollectionBase是強制類型集合的基類,通過實現這個類可以實現強制類型 |
| IDataAdapter | 適配器模式 | IDataAdapter定義了數據庫與DataSet之間的橋接器, 針對不同的數據源的DataAdapter瞌睡實現程序與數據源的松耦合 |
十、設計模式的分類
1、創建型模式
通過一個專門實例化的類來獲得具體的對象,通常我們將稱這個類為“工廠”,將與實例化相關的模式稱為“創建型模式”。
