zoukankan      html  css  js  c++  java
  • 设计模式七大原则之依赖倒转原则

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

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

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

           在实现一来倒转原则时,需要针对抽象层编程,而将具体类的对象通过依赖注入的方式注入到其他对象中。依赖注入是指当一个对象要与其他对象发生依赖关系时,通过抽象来注入所依赖的对象。常用的注入方式有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     }

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

  • 相关阅读:
    Dubbo服务者消费者提供者案例实现
    spring核心组件
    spring为什么要注入接口
    小菜鸡进阶之路_Second week之元组、列表、集合、字典对比.
    小菜鸡进阶之路-First week
    光学公式推到——(物象位置) 1/u+1/v=1/f
    C#问题——调用事件时其他信息: 未将对象引用设置到对象的实例。
    工业相机全局曝光和卷帘曝光的区别
    相机加接圈的作用和缺点
    C#——数组维度/行数/列数/长度区别
  • 原文地址:https://www.cnblogs.com/yangda/p/11924876.html
Copyright © 2011-2022 走看看