国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

設計模式六大原則(3)--依賴倒置原則

2019-11-17 03:00:59
字體:
來源:轉載
供稿:網友
設計模式六大原則(3)--依賴倒置原則

定義:

高層次的模塊不應該依賴于低層次的模塊,兩者都應該依賴于抽象接口;抽象接口不應該依賴于具體實現。而具體實現則應該依賴于抽象接口。依賴倒置原則英文全稱為Dependence Inversion PRinciple,簡稱為DIP。

問題由來:

類A直接依賴類B,假如要將類A改為依賴類C,則必須通過修改類A的代碼來達成。這種場景下,類A一般是高層模塊,負責復雜的業務邏輯;類B和類C是低層模塊,負責基本的原子操作;假如修改類A,會給程序帶來不必要的風險。

解決方案:

將類A修改為依賴接口I,類B和類C各自實現接口I,類A通過接口I間接與類B或者類C發生聯系,則會大大降低修改類A的幾率。

采用依賴倒置原則可以減少類間的耦合性,提高系統的穩定性,減少并行開發引起的風險,提高代碼的可讀性和可維護性。依賴倒置原則的核心就是面向接口編程,理解了面向接口編程也就理解了依賴倒置原則。下面通過一個司機開車的例子簡單說明一下:

有一個奔馳車類,奔馳車可以運行,方法為Run,司機類有一個開奔馳車的方法Drive。司機和奔馳車類的代碼如下所示:

///<summary>/// 奔馳車類///</summary>public class Benz{//奔馳車運行public void Run(){Console.WriteLine("奔馳車開始運行...");}}///<summary>/// 司機類///</summary>public class Driver{public void Drive(Benz benz){benz.Run();}}

主函數司機小明開動奔馳車,代碼如下:

class Client{static void Main(string[] args){//一輛奔馳車var benz = new Benz();//司機小明var xiaoming = new Driver();//小明開奔馳xiaoming.Drive(benz);Console.ReadKey();}}

上面實現了司機開奔馳車的場景,但是對于實際的業務來說,需求是不斷變化的。在技術上"變更才顯真功夫",只有在"變化"過程中才能知道自己設計或程序是否是松耦合。上面的例子,我們加點要求:司機也要會開寶馬車。要完成這個必須先有個寶馬車類,如下所示:

///<summary>/// 寶馬車類///</summary>public class Bmw{//寶馬車運行public void Run(){Console.WriteLine("寶馬車開始運行...");}}

盡管有了寶馬車類,但是司機根本木有開寶馬車的方法。你可能會說,木有那就加上開寶馬車的方法!這樣,是解決了一時的問題,但是還有法拉利、賓利等車呢?因此,是我們的設計出現了問題:司機類和奔馳車類之間是一個緊耦合的關系,其導致的結果就是系統的可維護性大大降低,可讀性降低,兩個相似的類需要閱讀兩個文件,這顯然不可取。還有穩定性:固化的、健壯的才是穩定的。這里只是增加了一個車類就需要修改司機類,這不是穩定性,這是易變性。被依賴者的變更竟然讓依賴者來承擔修改的成本,這樣的依賴關系誰肯承擔!

在實際項目的開發中,要盡可能減少并行開發引起的風險。并行開發最大的風險就是風險擴散,本來只是一段程序的錯誤或異常,逐步波及一個功能,一個模塊,甚至到最后毀壞了整個項目。因為一個團隊,幾十人甚至上百人人開發,各人負責不同的功能模塊,甲負責汽車類的建造,乙負責司機類的建造,在甲沒有完成的情況下,乙是不能完全地編寫代碼的,缺少汽車類,編譯器根本就不會讓你通過!在缺少Benz類的情況下,Driver類能編譯嗎?更不要說是單元測試了!這種相互依存的關系在實際開發中是不被允許的,另一個角度來說這樣開發只能挨個進行修改,并且每一項修改可能牽一發而動全身。這種模式 在現在的大中型項目中已經是完全不能勝任了,一個項目是一個團隊的協作結果,一個人不可能了解所有的業務和所有的技術,要協作就要并行開發,要并行開發就要解決模塊之間的項目依賴關系,然后依賴倒置原則就隆重出場了,呵呵。

依賴倒置原則的核心就是接口,下面我們為車和司機定義兩個接口ICar和IDriver,代碼如下所示:

///<summary>/// 汽車接口///</summary>public interface ICar{void Run();}///<summary>/// 司機接口///</summary>public interface IDriver{void Drive(ICar car);}

然后讓上面定義的司機和汽車(寶馬和奔馳)各自繼承自己對應的接口,代碼如下所示:

///<summary>/// 奔馳車類///</summary>public class Benz:ICar{//奔馳車運行public void Run(){Console.WriteLine("奔馳車開始運行...");}}///<summary>/// 寶馬車類///</summary>public class Bmw:ICar{//寶馬車運行public void Run(){Console.WriteLine("寶馬車開始運行...");}}///<summary>/// 司機類///</summary>public class Driver:IDriver{public void Drive(ICar car){car.Run();}}

此時的類的結構圖如下所示:

在開發實現業務需求時,我們應該謹記抽象不依賴細節。在這里,汽車和司機的接口都不依賴細節(具體的實現類),看到這應該對依賴倒置原則理解的差不多了吧。

依賴倒置原則是一個指導思想,是通過抽象(接口或抽象類)使各個類或模塊的實現彼此獨立,不互相影響,實現模塊間的松耦合,為更好使用此原則,在實際項目中我們要按如下方法使用:

  • 每一個類都要盡可能有接口或抽象類和兩者都有,也不可過分去生搬硬套依賴倒置原則。
  • 變量的顯示類型盡量是接口或者抽象類。

  • 任何類都不要從具體類中派生。

  • 盡量不要覆寫基類的方法。

  • 結合里氏替換原則使用

依賴倒置原則是六個設計原則中最難以實現的原則,它是實現開閉原則的重要途徑,依賴倒置原則沒有實現,就別想實現對擴展開放,對修改關閉。在項目中,大家只要記住是"面向接口編程"就基本上抓住了依賴倒轉原則的核心。順便說一下,實際的項目投產上線和盈利是第一要務,因此設計模式的原則只是提供了指導思想,我們不應該主動去違背,但是限于實際情況不得不違背,否則即便設計得有多么好,架構多么完美,這都是扯淡的事情。一旦超過預期工期或者項目虧本,你老板不高興,然后你也會不高興的…


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 曲周县| 鹰潭市| 赣榆县| 繁昌县| 长治市| 阿瓦提县| 临西县| 龙江县| 昆明市| 兴安县| 南皮县| 聊城市| 诸暨市| 喀什市| 武冈市| 靖江市| 措勤县| 库伦旗| 博白县| 宁城县| 信宜市| 永登县| 翼城县| 巴塘县| 库尔勒市| 孟津县| 平塘县| 巴青县| 元阳县| 汉阴县| 新营市| 涿州市| 大港区| 从江县| 襄汾县| 江阴市| 苏尼特左旗| 东平县| 逊克县| 肥东县| 额济纳旗|