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

    基本介绍

    依赖原则是指:

    高层模块不应该依赖底层模块,二者都应该依赖其抽象

    抽象不应该依赖细节,细节应该依赖抽象

    依赖倒转的中心思想是面向接口编程

    依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比细节为基础的架构要稳定的多。在java中,抽象指的是接口或抽象类,细节就是具体的实现类。

    使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成

    应用实例

    Person接受消息的功能

    方式一:

    package cn.rabcheng.dependenceinversion;

    /**
    * @auther cheng
    * @create 2020-08-13 22:41
    * 依赖倒转原则
    */
    public class dependenceinversion1 {
    public static void main(String[] args) {

    Person person = new Person();
    person.receive(new Email());
    person.receive2(new Weixin());


    }
    }

    class Email{
    public String getInfo(){
    return "电子邮件信息:hello world";
    }
    }

    class Weixin{
    public String getInfo(){
    return "微信消息:hello ok";
    }
    }

    //完成Person接受消息的功能
    class Person{
    public void receive(Email email){
    System.out.println(email.getInfo());
    }

    public void receive2(Weixin weixin){
    System.out.println(weixin.getInfo());

    }
    }

    电子邮件信息:hello world
    微信消息:hello ok

    方式一的分析:

    简单,比较容易想到、实现

    如果我们获取的对象是微信、短信等等,则新增类,同时Person也要增加相应的接受方法

    解决思路:引入一个抽象的接口IReceiver,表示接收者,这样Person类与IReceiver发生依赖

    因为Email,Weixin等等属于接收的范围,他们各自实现IReceiver接口就行,这样我们就符合依赖倒转的原则

    方式二:

     1 package cn.rabcheng.dependenceinversion;
     2 
     3 /**
     4  * @auther cheng
     5  * @create 2020-08-13 22:57
     6  * 依赖倒转原则
     7  */
     8 public class dependenceinversion2 {
     9     public static void main(String[] args) {
    10 
    11         //客户端无需改变
    12         Person2 person2 = new Person2();
    13         person2.receive(new Email2());
    14         person2.receive(new Weixin2());
    15 
    16 
    17     }
    18 }
    19 
    20 //定义接口
    21 interface IReceiver{
    22     String getInfo();
    23 }
    24 
    25 
    26 class Email2 implements IReceiver{
    27     @Override
    28     public String getInfo() {
    29         return "电子邮件信息:hello world";
    30     }
    31 }
    32 
    33 //增加微信
    34 class Weixin2 implements IReceiver{
    35     @Override
    36     public String getInfo() {
    37         return "微信消息:hello ok";
    38     }
    39 }
    40 
    41 class Person2{
    42     //person2依赖接口
    43     public void receive(IReceiver iReceiver){
    44         System.out.println(iReceiver.getInfo());
    45     }
    46 }
    47 电子邮件信息:hello world
    48 微信消息:hello ok

    这样只需要增加Weixin类,不用增加Person类里面的方法,让Person类和IReceiver发生依赖关系。

    依赖关系传递的三种方式和应用案例

    接口传递

    构造方法传递

    setter方法传递

      1 package cn.rabcheng.dependenceinversion;
      2 
      3 /**
      4  * @auther cheng
      5  * @create 2020-08-13 23:10
      6  * 依赖传递
      7  */
      8 public class DependencyPass {
      9     public static void main(String[] args) {
     10 
     11 //        方式一:通过接口传递
     12 //        Open open = new Open();
     13 //        open.open(new XiaoMi());
     14 
     15 //        方式二:通过构造方法传递
     16 //        Open open = new Open(new XiaoMi());
     17 //        open.open();
     18 
     19 //        方式三:通过setter方法传递
     20         Open open = new Open();
     21         XiaoMi xiaoMi = new XiaoMi();
     22         open.setter(xiaoMi);
     23         open.open();
     24     }
     25 }
     26 
     27 //方式一:通过接口传递依赖
     28 //开电视的接口
     29 //interface IOpen{
     30 //    void open(ITV itv);
     31 //}
     32 //
     33 ////电视机接口
     34 //interface ITV{
     35 //    void play();
     36 //}
     37 //
     38 //class XiaoMi implements ITV{
     39 //    @Override
     40 //    public void play() {
     41 //        System.out.println("小米电视,打开");
     42 //    }
     43 //}
     44 //
     45 //class Open implements IOpen{
     46 //    @Override
     47 //    public void open(ITV itv) {
     48 //        itv.play();
     49 //    }
     50 //}
     51 
     52 //方式二:通过构造方法传递依赖
     53 //interface IOpen{
     54 //    void open();
     55 //}
     56 //
     57 //interface ITV{
     58 //    void play();
     59 //}
     60 //
     61 //class XiaoMi implements ITV{
     62 //    @Override
     63 //    public void play() {
     64 //        System.out.println("小米电视,打开");
     65 //    }
     66 //}
     67 //
     68 //class Open implements IOpen{
     69 //    private ITV itv;
     70 //    public Open(ITV itv) {
     71 //        this.itv = itv;
     72 //    }
     73 //
     74 //    @Override
     75 //    public void open() {
     76 //        this.itv.play();
     77 //    }
     78 //}
     79 
     80 
     81 //方式三:通过setter方法传递
     82 interface IOpen{
     83     void open();
     84 }
     85 
     86 interface ITV{
     87     void play();
     88 }
     89 
     90 class Open implements IOpen{
     91     private ITV itv;
     92 
     93     public void setter(ITV itv){
     94         this.itv = itv;
     95     }
     96     @Override
     97     public void open() {
     98         this.itv.play();
     99     }
    100 }
    101 
    102 class XiaoMi implements ITV{
    103     @Override
    104     public void play() {
    105         System.out.println("小米电视,打开");
    106     }
    107 }

    依赖倒转原则的注意事项和细节:

    底层模块尽量都要有抽象类或接口,或者两者都有,程序稳定性更好

    变量的声明类型尽量是抽象类或接口,这样我们的变量引用和实际对象间,就存在一个缓冲层,利于程序扩展和优化

    继承时应遵循里氏替换原则

  • 相关阅读:
    迭代器
    逻辑量词
    How to distinguish between strings in heap or literals?
    Is the “*apply” family really not vectorized?
    power of the test
    The Most Simple Introduction to Hypothesis Testing
    析构函数允许重载吗?
    C++中析构函数的作用
    在C#中的构造函数和解析函数
    c++构造函数与析构函数
  • 原文地址:https://www.cnblogs.com/Rabcheng/p/13499703.html
Copyright © 2011-2022 走看看