设计模式七大原则之依赖倒转原则

依赖倒转原则:抽象不应该依赖于细节,细节应当依赖于抽象,换言之,要针对接口编程,而不是针对实现编程。

        依赖倒转原形要求程序代码中传递参数时或在关联关系中,进来引用层次高的抽象层类,即使用接口和抽象类进行变量类型声明、参数类型声明、方法返回类型声明,以及数据类型的转换等,而不要用具体类来做这些事情。为了确保该原则的应用,一个具体类应当只实现接口或抽象中声明过的方法,而不要给出多余的方法,否则将无法调用到在子类中增加的新方法。

        在引入抽象层后,系统将具有很好的灵活性,在程序中尽量使用抽象层来进行编程,而将具体类写在配置文件中,这样一来,如果系统行为发生变化,只需要对抽象层进行扩展,并修改配置文件,而无须修改原有系统的源代码,就能扩展系统的功能,满足开闭原则的要求。

       在实现一来倒转原则时,需要针对抽象层编程,而将具体类的对象通过依赖注入的方式注入到其他对象中。依赖注入是指当一个对象要与其他对象发生依赖关系时,通过抽象来注入所依赖的对象。常用的注入方式有3种:构造注入,设置注入和接口注入。构造注入是指通过构造函数来传入具体类的对象,设值注入是指通过set方法来传入具体类的对象,而接口注入是指实现该接口中声明的业务方法来传入具体类的对象。这些方法在定义时使用的是抽象类型,在运行时再传入具体类型的对象。这些方法在定义时使用的是抽象类型,在运行时再传入具体类型的对象,由子类对象来覆盖父类对象。

代码示例:

 1   //具体Jim人类
 2     public class Jim
 3     {
 4         public void eat(Apple apple)
 5         {
 6             Console.WriteLine("Jim eat " + apple.getName());
 7         }
 8     }
 9     //具体苹果类
10     public class Apple
11     {
12         public String getName()
13         {
14             return "apple";
15         }
16     }
17     public class Client
18     {
19         public static void main(String[] args)
20         {
21             Jim jim = new Jim();
22             Apple apple = new Apple();
23             jim.eat(apple);
24         }
25     }

 

        上面的例子比较简单,Jim吃苹果,看起来没什么问题,但此刻需要改变,小李吃苹果,小王吃香蕉呢?这个时候我们需要根据依赖倒转重新设计一下。

 1    //人接口
 2     public interface People
 3     {
 4         public void eat(Fruit fruit);//人都有吃的方法,不然都饿死了
 5     }
 6     //水果接口
 7     public interface Fruit
 8     {
 9         public String getName();//水果都是有名字的
10     }
11     //具体Jim人类
12     public class Jim : People
13     {
14         public void eat(Fruit fruit)
15         {
16             Console.WriteLine("Jim eat " + fruit.getName());
17         }
18     }
19     //具体苹果类
20     public class Apple : Fruit
21     {
22         public String getName()
23         {
24             return "apple";
25         }
26     }
27     //具体香蕉类
28     public class Banana : Fruit
29     {
30         public String getName()
31         {
32             return "banana";
33         }
34     }
35 
36     class Program
37     {
38         static void Main(string[] args)
39         {
40             People jim = new Jim();
41             Fruit apple = new Apple();
42             Fruit Banana = new Banana();//这里符合了里氏替换原则
43             jim.eat(apple);
44             jim.eat(Banana);
45 
46             Console.ReadLine();
47         }
48     }

    这个时候定义了把高层接口抽象化了,只需要对新增的实现类进行修改就可以了。

 

posted @ 2019-11-24 22:32  虔城墨客  阅读(447)  评论(0编辑  收藏  举报