標籤:
What
Dependence Inversion Principle(DIP):高層模組不應該依賴底層模組,都應該依賴於抽象;抽象不應該依賴於具體,具體依賴於抽象
Why
若高層依賴於底層,那麼底層的變動也會導致高層的變動,這就會導致模組的複用性降低而且大大提高了開發的成本。若是依賴於抽象的話,那麼是比較穩定的,底層或者高層的變動都不會互相影響。
How
很多地方引用的個人覺得也非常有代表性的一個例子:公司是福特和本田公司的金牌夥伴,現要求開發一套自動駕駛系統,只要汽車上安裝該系統就可以實現無人駕駛,該系統可以在福特和本田車上使用,只要這兩個品牌的汽車使用該系統就能實現自動駕駛。
福特汽車類,包含三個方法,啟動、停止、轉彎
class FordCar { public void Run() { Console.WriteLine("FordCar run"); } public void Stop() { Console.WriteLine("FordCar stop"); } public void Turn() { Console.WriteLine("FordCar turn"); } }
宏達汽車類,包含三個方法,啟動、停止、轉彎
class HondaCar { public void Run() { Console.WriteLine("HondaCar run"); } public void Stop() { Console.WriteLine("HondaCar stop"); } public void Turn() { Console.WriteLine("HondaCar turn"); } }
自動駕駛系統,有三個方法啟動汽車、停止汽車、汽車轉向
class AutoSystem { HondaCar hondaCar = new HondaCar(); FordCar fordCar = new FordCar(); CarType type; public AutoSystem(CarType type) { this.type = type; } public void RunCar() { if (type == CarType.Honda) { hondaCar.Run(); } else if (type == CarType.Ford) { fordCar.Run(); } } public void StopCar() { if (type == CarType.Honda) { hondaCar.Stop(); } else if (type == CarType.Ford) { fordCar.Stop(); } } public void TurnCar() { if (type == CarType.Honda) { hondaCar.Turn(); } else if (type == CarType.Ford) { fordCar.Turn(); } } }
目前來看,是滿足需求的,但是隨著發展業務也在發展,現在如果發展了夥伴,需要對其他品牌的汽車添加自動駕駛系統,比如紅旗、奇瑞等品牌,那麼如果沿用以前的方式,就需要去修改AutoSystem了,先增加兩個新的品牌汽車的對象,然後在啟動汽車、停止汽車、汽車轉向中進行修改增加分支語句對不同的品牌來進行判斷然後加上各種操作,這樣就違背的OCP,而且複雜的分支語句也會容易造成錯誤,如果以後再繼續擴充其他的品牌的話,那麼這樣的程式肯定是不易於維護的,程式的健壯性是較差的,大大的增加了開發的成本。那麼敏感的同學已經看出來,既然不同的汽車品牌之間都擁有相同的行為,那麼為什麼不定義一個介面呢?現在我們先來定義一個介面,然後將各個品牌的汽車實現這個介面實現,那麼在AutoSystem中我們就可以針對定義的介面操作了。
interface ICar { void Run(); void Stop(); void Turn(); }
自動駕駛系統也就是高層模組現在針對的是這個抽象的介面,無論什麼汽車,只要實現了ICar介面,就能進行相關的操作。
class AutoSystem { ICar car; public AutoSystem(ICar car) { this.car = car; } public void RunCar() { car.Run(); } public void StopCar() { car.Stop(); } public void TurnCar() { car.Turn(); } }
福特汽車類也就是底層模組,實現了ICar介面,現在依賴的是抽象的介面
class FordCar : ICar { public void Run() { Console.WriteLine("FordCar run"); } public void Stop() { Console.WriteLine("FordCar stop"); } public void Turn() { Console.WriteLine("FordCar turn"); } }
宏達汽車類也就是底層模組,實現了ICar介面,現在依賴的是抽象的介面
class HondaCar : ICar { public void Run() { Console.WriteLine("HondaCar run"); } public void Stop() { Console.WriteLine("HondaCar stop"); } public void Turn() { Console.WriteLine("HondaCar turn"); } }
當高層模組依賴底層的時候,那麼高層的複用性就較差,就如上例所說的增加汽車品牌種類。如果高層與底層都是依賴於抽象的話,那麼高層複用性就較好,因為通過繼承象出來的介面實現多態,那麼複用的地方就多了,這樣的設計無疑是較為穩定的。
依賴倒置原則