03、依赖倒转原则
- 依赖倒转原则:1)高层模块不应该依赖于低层模块,二者应该依赖其抽象。 2)抽象不应该依赖细节,细节应该依赖抽象。3)依赖倒转原则的中心思想是面向接口编程。4)相对于细节的多边性,抽象的东西要稳定的多。以抽象为基础搭建的框架比细节为基础的架构要稳定的多,在java中抽象指的是接口或者是抽象类,细节就是实现类。5)使用接口或者抽象类的目的是制定好规范,而不涉及任何具体的操作,把展示的细节任务交给他们的实现类去完成。
1 public class DependecyInversion { 2 3 public static void main(String[] args) { 4 Person person = new Person(); 5 person.receive(new Email()); 6 } 7 8 } 9 10 11 class Email { 12 public String getInfo() { 13 return "电子邮件信息: hello,world"; 14 } 15 } 16 17 //完成Person接收消息的功能 18 //方式1分析 19 //1. 简单,比较容易想到 20 //2. 如果我们获取的对象是 微信,短信等等,则新增类,同时Perons也要增加相应的接收方法 21 //3. 解决思路:引入一个抽象的接口IReceiver, 表示接收者, 这样Person类与接口IReceiver发生依赖 22 // 因为Email, WeiXin 等等属于接收的范围,他们各自实现IReceiver 接口就ok, 这样我们就符号依赖倒转原则 23 class Person { 24 public void receive(Email email ) { 25 System.out.println(email.getInfo()); 26 } 27 }
- 改进方案:
1 public class DependecyInversion { 2 3 public static void main(String[] args) { 4 //客户端无需改变 5 Person person = new Person(); 6 person.receive(new Email()); 7 8 person.receive(new WeiXin()); 9 } 10 11 } 12 13 //定义接口 14 interface IReceiver { 15 public String getInfo(); 16 } 17 18 class Email implements IReceiver { 19 public String getInfo() { 20 return "电子邮件信息: hello,world"; 21 } 22 } 23 24 //增加微信 25 class WeiXin implements IReceiver { 26 public String getInfo() { 27 return "微信信息: hello,ok"; 28 } 29 } 30 31 //方式2 32 class Person { 33 //这里我们是对接口的依赖 34 public void receive(IReceiver receiver ) { 35 System.out.println(receiver.getInfo()); 36 } 37 }
- 依赖关系传递的三种方式:
- 通过接口传递实现依赖。
1 // 方式1: 通过接口传递实现依赖 2 // 开关的接口 3 // interface IOpenAndClose { 4 // public void open(ITV tv); //抽象方法,接收接口 5 // } 6 // 7 // interface ITV { //ITV接口 8 // public void play(); 9 // } 10 // 11 // class ChangHong implements ITV { 12 // 13 // @Override 14 // public void play() { 15 // // TODO Auto-generated method stub 16 // System.out.println("长虹电视机,打开"); 17 // } 18 // 19 // } 20 //// 实现接口 21 // class OpenAndClose implements IOpenAndClose{ 22 // public void open(ITV tv){ 23 // tv.play(); 24 // } 25 // }
- 通过构造函数传递依赖。
1 // 方式2: 通过构造方法依赖传递 2 // interface IOpenAndClose { 3 // public void open(); //抽象方法 4 // } 5 // interface ITV { //ITV接口 6 // public void play(); 7 // } 8 // class OpenAndClose implements IOpenAndClose{ 9 // public ITV tv; //成员 10 // public OpenAndClose(ITV tv){ //构造器 11 // this.tv = tv; 12 // } 13 // public void open(){ 14 // this.tv.play(); 15 // } 16 // }
- 通过seter方法实现依赖传递。
1 // 方式3 , 通过setter方法传递 2 interface IOpenAndClose { 3 public void open(); // 抽象方法 4 5 public void setTv(ITV tv); 6 } 7 8 interface ITV { // ITV接口 9 public void play(); 10 } 11 12 class OpenAndClose implements IOpenAndClose { 13 private ITV tv; 14 15 public void setTv(ITV tv) { 16 this.tv = tv; 17 } 18 19 public void open() { 20 this.tv.play(); 21 } 22 }
依赖倒转原则注意事项:1)低层模块尽量都要有抽象类或者接口,或者两者都有,程序的稳定性更好。2)变量的声明类型尽量是接口或者抽象方法,这样我们的变量引用和实际对象间,就存在一个缓冲层,利于程序的扩展和优化。3)遵循里式替换原则。
- 通过接口传递实现依赖。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构