JAVA設計原則之依賴倒置原則

Whatjava

  Dependence Inversion Principle(DIP):高層模塊不該該依賴底層模塊,都應該依賴於抽象;抽象不該該依賴於具體,具體依賴於抽象this

  Why設計

  若高層依賴於底層,那麼底層的變更也會致使高層的變更,這就會致使模塊的複用性下降並且大大提升了開發的成本。如果依賴於抽象的話,那麼是比較穩定的,底層或者高層的變更都不會互相影響。code

  How對象

  不少地方引用的我的以爲也很是有表明性的一個例子:公司是福特和本田公司的金牌合做夥伴,現要求開發一套自動駕駛系統,只要汽車上安裝該系統就能夠實現無人駕駛,該系統能夠在福特和本田車上使用,只要這兩個品牌的汽車使用該系統就能實現自動駕駛。繼承

  福特汽車類,包含三個方法,啓動、中止、轉彎接口

class FordCar
    {
        public void Run()
        {
            Console.WriteLine("FordCar run");
        }

        public void Stop()
        {
            Console.WriteLine("FordCar stop");
        }

        public void Turn()
        {
            Console.WriteLine("FordCar turn");
        }
    }

宏達汽車類,包含三個方法,啓動、中止、轉彎ip

class HondaCar
    {
        public void Run()
        {
            Console.WriteLine("HondaCar run");
        }

        public void Stop()
        {
            Console.WriteLine("HondaCar stop");
        }

        public void Turn()
        {
            Console.WriteLine("HondaCar turn");
        }
    }

自動駕駛系統,有三個方法啓動汽車、中止汽車、汽車轉向ci

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");
        }
    }

 當高層模塊依賴底層的時候,那麼高層的複用性就較差,就如上例所說的增長汽車品牌種類。若是高層與底層都是依賴於抽象的話,那麼高層複用性就較好,由於經過繼承象出來的接口實現多態,那麼複用的地方就多了,這樣的設計無疑是較爲穩定的。

相關文章
相關標籤/搜索