设计模式-依赖倒转原则

依赖倒转原则

1)高层模块不应该依赖低层模块,而这应该依赖其抽象(接口,抽象类)
2)抽象不应该依赖细节,细节应该依赖抽象
3)依赖倒转(倒置)的中心思想面向接口编程
4)设计理念:相对于细节的多变性,抽象的东西要稳定得多,以抽象为基础搭建的架构比以细节搭建的架构要稳定的多.在Java中,抽象指的是接口或抽象类,细节就是具体的实现类.
5)使用接口和抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务教给他们的实现类去完成

依赖关系传递的三种方式

接口传递

	public class DependecyInversion3 {
	    public static void main(String[] args) {
	        OpenAndClose openAndClose = new OpenAndClose();
	        openAndClose.open(new TV());
	    }
	}

/**
 * 实现ITV抽象接口
 */
class TV implements ITV {
    @Override
    public void play() {
        System.out.println("打开电视机");
    }
}

/**
 * 接口IOpenAndClose
 */
interface IOpenAndClose {
    //抽象方法接收接口
    void open(ITV itv);
}
/**
 * 接口ITV
 */
interface ITV {
    void play();
}

/**
 * 实现IOpenAndClose接口
 */
class OpenAndClose implements IOpenAndClose {
    @Override
    public void open(ITV itv) {
        itv.play();
    }
}

构造方法传递

public class DependecyInversion4 {
    public static void main(String[] args) {
        OpenAndClose openAndClose = new OpenAndClose(new TV());
        openAndClose.open();
    }
}

/**
 * 实现ITV抽象接口
 */
class TV implements ITV {
    @Override
    public void play() {
        System.out.println("打开电视机");
    }
}

/**
 * 接口IOpenAndClose
 */
interface IOpenAndClose {
    void open();//抽象方法
}
/**
 * 接口ITV
 */
interface ITV {
    void play();
}

/**
 * 实现IOpenAndClose接口
 */
class OpenAndClose implements IOpenAndClose {
    /**
     * 属性成员
     */
   public ITV itv;

    /**
     * 构造器
     * @param itv
     */
   public OpenAndClose(ITV itv) {
       this.itv = itv;
   }
    @Override
    public void open() {
        this.itv.play();
    }
}

setter方式传递

public class DependecyInversion5 {
    public static void main(String[] args) {
        OpenAndClose openAndClose = new OpenAndClose();
        openAndClose.setItv(new TV());
        openAndClose.open();
    }
}

/**
 * 实现ITV抽象接口
 */
class TV implements ITV {
    @Override
    public void play() {
        System.out.println("打开电视机");
    }
}

/**
 * 接口IOpenAndClose
 */
interface IOpenAndClose {
    void open();//抽象方法
}
/**
 * 接口ITV
 */
interface ITV {
    void play();
}

/**
 * 实现IOpenAndClose接口
 */
class OpenAndClose implements IOpenAndClose {
    /**
     * 属性成员
     */
    public ITV itv;

    /**
     *  通过setter方法传递
     * @param itv
     */
    public void setItv(ITV itv) {
        this.itv = itv;
    }

    @Override
    public void open() {
        this.itv.play();
    }
}

方案一

public class DependecyInversion {
    public static void main(String[] args) {
        Person person = new Person();
 		//如需要从短信或微信接收消息则需要修改客户端
        person.receive(new Email());
    }
}

class Email {
    public String getInfo() {
        return "电子邮件信息 Hello Word";
    }
}

/**
 * 方案一
 * 分析 :
 *       1. 简单,容易想到
 *       2. 如果从微信或者短信等,则需要新增微信或短信类,同时Person也要新增相应的接受方案
 * 解决 :	方案二
 *       1.引入一个抽象接口IReceiver,表示接受者,Person与接口IReceiver发生依赖
 *       2. Email,微信,短信属于接收范围,它们各自实现IReceiver接口,这样就符合依赖倒转原则
 */
class Person {
    public void receive(Email email) {
        System.out.println(email.getInfo());
    }
}

在这里插入图片描述

方案二

public class DependecyInversion2 {
    public static void main(String[] args) {
        //客户端没有改变
        Person person = new Person();
        person.receive(new Email());
        person.receive(new WeiXin());
    }
}

/**
 * 定义接口
 */
interface IReceiver {
    String getInfo();
}

/**
 * Email类实现接口IReceiver
 */
class Email implements IReceiver {
    @Override
    public String getInfo() {
        return "电子邮件信息 Hello Word";
    }
}

/**
 * 新增微信类实现接口IReceiver
 */
class WeiXin implements IReceiver {
    @Override
    public String getInfo() {
        return "微信信息 Hello Word";
    }
}

/**
 * 方案二
 * 分析 :
 * 1. 对接口的依赖
 * 2. 改动特别少,就可以实现
 */
class Person {
    public void receive(IReceiver iReceiver) {
        System.out.println(iReceiver.getInfo());
    }
}

在这里插入图片描述

依赖注入的注意事项和细节

1)低层模块尽量都要有抽象类或接口,或两者都有,程序稳定性更好
2)变量的声明类型尽量使抽象类或接口,这样我们的变量引用和实际对象间,就存在一个缓冲层,利于程序扩展和优化
3)继承时遵守里氏替换原则
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值