设计模式原则之:依赖倒转原则
基本介绍:
- 高层模块不应该依赖与底层模块,二者都应该依赖其抽象
- 抽象不应该依赖细节,细节应该依赖抽象
- 依赖倒转(倒置)的中心思想是面向接口编程
- 依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳定的多,在Java中,抽象指的是接口或抽象类,细节就是具体的实现类
- 使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给它们的实现类去完成
错误的案例+分析说明
/** * @description: 依赖倒转错误案例 * @author: abel.he * @date: 2023-08-02 **/ public class DependencyInversionError { public static void main(String[] args) { Person person = new Person(); person.receive(new Email()); } } class Email { public String info() { return "电子邮件信息:info"; } } /** * 完成Person接受消息的功能 * 分析: * 1、简单、比较容易得到 * 2、如果增加其他方法 如微信,短信等等 则新增类,同时Person也要增加相应的接受方法 * 3、解决思路,引入一个抽象接口IReceiver,表示接受者,这样Person类与接口IReceiver发生依赖 * 微信,短信 等等属于接受的范围,它们各自实现IReceiver接口就ok,这样就符合依赖倒转原则 */ class Person { public void receive(Email email) { System.out.println(email.info()); } }
引出的案例
/** * @description: 依赖倒转正确案例 * @author: abel.he * @date: 2023-08-02 **/ public class DependencyInversionCorrect { public static void main(String[] args) { Person1 person = new Person1(); person.receive(new Email1()); person.receive(new WeChat()); } } interface IReceiver { String info(); } class Email1 implements IReceiver { public String info() { return "电子邮件信息:info"; } } class WeChat implements IReceiver { @Override public String info() { return "微信信息:info"; } } class Person1 { public void receive(IReceiver receiver) { System.out.println(receiver.info()); } }
依赖关系传递的三种方式和应用场景
1.接口传递
/** * @description: 依赖倒装接口传递 * @author: abel.he * @date: 2023-08-02 **/ public class DependencyPass { public static void main(String[] args) { ChangHong changHong = new ChangHong(); OpenAndClosed openAndClosed = new OpenAndClosed(); openAndClosed.show(changHong); } } interface ITv { void play(); } class ChangHong implements ITv { @Override public void play() { System.out.println("长虹电视机:打开"); } } interface IOpenAndClosed { void show(ITv tv); } class OpenAndClosed implements IOpenAndClosed { @Override public void show(ITv tv) { tv.play(); } }
2.构造防范传递
/** * @description: 构造器传递 * @author: abel.he * @date: 2023-08-02 **/ public class DependencyPass1 { public static void main(String[] args) { ChangHong1 hong1 = new ChangHong1(); OpenAndClosed1 openAndClosed1 = new OpenAndClosed1(hong1); openAndClosed1.show(); } } interface ITv1 { void play(); } class ChangHong1 implements ITv1 { @Override public void play() { System.out.println("长虹电视:打开"); } } interface IOpenAndClosed1 { void show(); } class OpenAndClosed1 implements IOpenAndClosed1{ private ITv1 tv; public OpenAndClosed1(ITv1 tv) { this.tv = tv; } @Override public void show() { tv.play(); } }
3.setter方法传递
/** * @description: 依赖倒转案例 setter传递 * @author: abel.he * @date: 2023-08-02 **/ public class DependencyPass2 { public static void main(String[] args) { ChangHong2 changHong2 = new ChangHong2(); OpenAndClosed2 openAndClosed2 = new OpenAndClosed2(); openAndClosed2.setTv2(changHong2); openAndClosed2.show(); } } interface ITv2 { void play(); } class ChangHong2 implements ITv2 { @Override public void play() { System.out.println("长虹2 打开"); } } interface IOpenAndClosed2 { void show(); } class OpenAndClosed2 implements IOpenAndClosed2 { private ITv2 tv2; public void setTv2(ITv2 tv2) { this.tv2 = tv2; } @Override public void show() { tv2.play(); } }