依賴倒置原則

所謂依賴倒置原則(Dependence Inversion Principle)就是要依賴於抽象,不要依賴於具體。編程

簡單的說就是對抽象進行編程,不要對實現進行編程,這樣就下降了客戶與實現模塊間的耦合。this

面向過程的開發,上層調用下層,上層依賴於下層,當下層劇烈變化時,上層也要跟着變化,這就會致使模塊的複用性下降並且大大提升了開發的成本。spa

面向對象的開發很好的解決了這個問題,通常的狀況下抽象的變化機率很小,讓用戶程序依賴於抽象,實現的細節也依賴於抽象。即便實現細節不斷變化,只要抽象不變,客戶程序就不須要變化。設計

這大大下降了客戶程序域實現細節的耦合度。code

好比一個合資汽車公司如今要求開發一個自動駕駛系統,只要汽車上安裝上這個系統,就能夠實現無人駕駛,該系統能夠在福特車系列和本田車系列上使用。面向過程的結構圖:對象

面向過程的設計:blog

public class HondaCar
    {
        public void Run() { Console.WriteLine("本田車啓動了!"); }
        public void Turn() { Console.WriteLine("本田車拐彎了!"); }
        public void Stop() { Console.WriteLine("本田車中止了!"); }
    }

public class FordCar
    {
        public void Run() { Console.WriteLine("福特車啓動了!"); }
        public void Turn() { Console.WriteLine("福特車拐彎了!"); }
        public void Stop() { Console.WriteLine("福特車中止了!"); }
    }

public class AutoSystem
    {
        public enum CarType{ Ford,Fonda}
        private HondaCar hondcar=new HondaCar();
        private FordCar fordcar=new FordCar();
        private CarType type;
        
        public AutoSystem(CarType carType)
        {
            this.type = carType;
        }

        public void RunCar()
        {
            if (this.type == CarType.Fonda)
            {
                hondcar.Run();
            }
            else if (this.type == CarType.Ford)
            {
                fordcar.Run();
            }
        }
        
        public void StopCar()
        {
            if (this.type == CarType.Fonda)
            {
                hondcar.Stop();
            }
            else if (this.type == CarType.Ford)
            {
                fordcar.Stop();
            }
        }

        public void TurnCar()
        {
            if (this.type == CarType.Fonda)
            {
                hondcar.Turn();
            }
            else if (this.type == CarType.Ford)
            {
                fordcar.Turn();
            }
        }
    }

顯然這個實現代碼也可知足如今的需求。
可是如何如今公司業務規模擴大了,該自動駕駛系統還要把吉普車也兼容了。這些就須要修改AutoSystem類以下:ip

public class AutoSystem
    {
        public enum CarType{ Ford,Fonda}
        private HondaCar hondcar=new HondaCar();
        private FordCar fordcar=new FordCar();
        private CarType type;
        
        public AutoSystem(CarType carType)
        {
            this.type = carType;
        }

        public void RunCar()
        {
            if (this.type == CarType.Fonda)
            {
                hondcar.Run();
            }
            else if (this.type == CarType.Ford)
            {
                fordcar.Run();
            }
        }
        
        public void StopCar()
        {
            if (this.type == CarType.Fonda)
            {
                hondcar.Stop();
            }
            else if (this.type == CarType.Ford)
            {
                fordcar.Stop();
            }
            else if (this.type == CarType.Jeep)
            {
                jeep.Stop();
            }
        }

        public void TurnCar()
        {
            if (this.type == CarType.Fonda)
            {
                hondcar.Turn();
            }
            else if (this.type == CarType.Ford)
            {
                fordcar.Turn();
            }
            else if (this.type == CarType.Jeep)
            {
                jeep.Turn();
            }
        }
    }

經過代碼分析得知,上述代碼也確實知足了需求,可是軟件是不斷變化的,軟件的需求也是變化的,若是未來業務又擴大了,該自動駕駛系統還有能實現通用、三菱、大衆汽車,這樣咱們不得不又要修改AutoSystem類了。
這樣會致使系統愈來愈臃腫,愈來愈大,並且依賴愈來愈多低層模塊,只有低層模塊變更,AutoSystem類就不得不跟着變更,致使系統設計變得很是脆弱和僵硬。
致使上面所述問題一個緣由是,含有高層策略的模塊,如AutoSystem模塊,依賴於它所控制的低層的具體細節的模塊(如FordCar和HondaCar)。
若是能使AutoSystem模塊獨立於它所控制的具體細節,而是依賴抽象,那麼咱們就能夠服用它了。這就是面向對象中的「依賴倒置」機制。ci


實現代碼以下:開發

public interface ICar
    {
        void Run();
        void Stop();
        void Turn();
    }

public class HondaCar:ICar
    {
        public void Run() { Console.WriteLine("本田車啓動了!"); }
        public void Turn() { Console.WriteLine("本田車拐彎了!"); }
        public void Stop() { Console.WriteLine("本田車中止了!"); }
    }

public class FordCar :ICar
    {
        public void Run() { Console.WriteLine("福特車啓動了!"); }
        public void Turn() { Console.WriteLine("福特車拐彎了!"); }
        public void Stop() { Console.WriteLine("福特車中止了!"); }
    }

public class Jeep:ICar
    {
        public void Run() { Console.WriteLine("福特車啓動了!"); }
        public void Turn() { Console.WriteLine("福特車拐彎了!"); }
        public void Stop() { Console.WriteLine("福特車中止了!"); }
    }

public class AutoSystem
    {
        private ICar car;
        
        public AutoSystem(ICar car)
        {
            this.car = car;
        }
        
        public void RunCar()
        {
            this.car.Run();
        }
        public void StopCar()
        {
            this.car.Stop();
        }
        public void TurnCar()
        {
            this.car.Turn();
        }
    }

如今Autosystem系統依賴於ICar這個抽象,而與具體的實現細節HondaCar:和FordCar無關,因此實現細節的變化不會影響AutoSystem.對於實現細節只要實現ICar便可。即實現細節依賴於ICar抽象。綜上所述:一個應用中的重要策略決定及業務 正是在這些高層的模塊中。也正是這些模塊包含這應用的特性。可是,當這些模塊依賴於低層模塊時,低層模塊的修改比較將直接影響到他們,迫使它們也改變。這種狀況是荒謬的。應該是處於高層的模塊去迫使那些低層的模塊發生改變。處於高層的模塊應優先於低層的模塊。不管如何高層模塊也不該該依賴於低層模塊。並且咱們想可以複用的是高層的模塊,只有高層模塊獨立於低層模塊時,複用纔有可能。總之,高層次的模塊不該該依賴於低層次的模塊,它們都應該依賴於抽象。抽象不該該依賴於具體,具體應該依賴於抽象。

相關文章
相關標籤/搜索