广东省建设厅投诉网站,安装wordpress出错,专注建设高端网站,网站如何做优化排名概述
高层模块不应依赖低层模块#xff0c;二者都应该依赖其抽象。而抽象不应依赖细节#xff0c;细节应该依赖抽象。依赖倒置原则的中心思想其实就是面向接口编程。 相对于细节的多变性#xff0c;抽象的东西会稳定的多#xff0c;所以以抽象为基础搭建的架构自然也会比以…概述
高层模块不应依赖低层模块二者都应该依赖其抽象。而抽象不应依赖细节细节应该依赖抽象。依赖倒置原则的中心思想其实就是面向接口编程。 相对于细节的多变性抽象的东西会稳定的多所以以抽象为基础搭建的架构自然也会比以细节为基础搭建的架构稳定的多。 使用接口或抽象类的目的是为了更好的制定规范而不涉及任何具体的操作把展现细节的任务交给他们的实现类去完成。 相信有读过spring framework源码的同学应该对这一点深以为是比如其核心接口之一的BeanFactory接口之下就继承了AutowireCapableBeanFactory、HierarchicalBeanFactory、ListableBeanFactory接口而这些接口又被多个抽象类有选择实现正是对依赖倒置原则的应用才使得spring framework 框架具有了极高的健壮性和扩展性。 三寸反骨
我们不妨从相反的角度出发写个反例看看会有什么问题今日反骨颇重就是不想遵循依赖倒置原则。 比如我们现在需要编写一个简单的Person类让他可以接受邮件消息即可。 反例
public class DependecyInversion {public static void main(String[] args) {Person person new Person();person.receive(new Email());}
}class Email{public String getInfo(){return 电子邮件信息 Hello,Email;}
}class Person {public void receive(Email email){System.out.println(email.getInfo());}
}编程的过程十分愉快如此简单的需求甚至不需要聪明的我们多思考一秒。运行效果也完全满足预期。 但是来了一个不好不坏的消息“能力需要扩展客户要求除了收到email的能力外微信消息也想收到” “反骨仔想了想不要紧我新增类同时Person类也要增加相应的方法就好了呀” 于是他加班1小时完成了这个需求自信满满的走了。 但是第二天又来了个不好不坏的消息“客户对产品很满意同时要求除了想收到email、微信消息之外还想扩展几十个软件的消息清单包含“QQ、微博、墨迹天气、钉钉…” 反骨仔爆炸了因为这个需求如果继续按他的思路去实现类也爆炸了。实现的方法更是爆炸到难以维护。 所以说一定要设计先行一个优秀的设计可能会占据相当长的开发时间但是会为后期的扩展和维护提供强有力的保障 优化设计
我们把时间推回两天前接到需求的我们首先便进行了深度剖析并达成了共识“依赖倒置原则必须遵守”于是有了如下代码
public class DependecyInversion {public static void main(String[] args) {Person person new Person();person.receive(new Email());person.receive(new WeChat());}
}
interface IReceive{public String getInfo();
}class Email implements IReceive{public String getInfo(){return 电子邮件信息 Hello,Email;}
}class WeChat implements IReceive{public String getInfo(){return 微信信息 Hello,WeChat;}
}class Person {public void receive(IReceive receiver){System.out.println(receiver.getInfo());}
}当客户说我要继续扩展几十个消息入口时我们会发现我们对于person类不需要做任何改动了不过是需要遵照IReceive接口规范去实现新扩展的业务细节就可以了。善莫大焉。 依赖关系传递三板斧
常见的依赖关系传递有三种方式
接口传递
public class DependencyPass {public static void main(String[] args) {ChangHong changHongTv new ChangHong();OpenAndClose openAndClose new OpenAndClose();openAndClose.open(changHongTv);}
}class ChangHong implements ITV,ITV2,ITV3{Overridepublic void play() {System.out.println(长虹电视机打开了。);}
}
interface IOpenAndClose{public void open(ITV tv);
}
interface ITV{public void play();
}
//实现接口
class OpenAndClose implements IOpenAndClose{Overridepublic void open(ITV tv) {tv.play();}
}构造方法传递
public class DependencyPass {public static void main(String[] args) {ChangHong changHongTv new ChangHong();OpenAndClose2 openAndClose2 new OpenAndClose2(changHongTv);openAndClose2.open();}}
class ChangHong implements ITV,ITV2,ITV3{Overridepublic void play() {System.out.println(长虹电视机打开了。);}
}
interface IOpenAndClose2{public void open();
}
interface ITV2{public void play();
}
class OpenAndClose2 implements IOpenAndClose2{public ITV2 tv;public OpenAndClose2(ITV2 tv){this.tv tv;}Overridepublic void open() {this.tv.play();}
}setter方法传递
public class DependencyPass {public static void main(String[] args) {ChangHong changHongTv new ChangHong();OpenAndClose3 openAndClose3 new OpenAndClose3();openAndClose3.setTv(changHongTv);openAndClose3.open();}}class ChangHong implements ITV,ITV2,ITV3{Overridepublic void play() {System.out.println(长虹电视机打开了。);}
}
interface IOpenAndClose3{public void open();public void setTv(ITV3 itv3);
}
interface ITV3{public void play();
}
class OpenAndClose3 implements IOpenAndClose3{private ITV3 itv3;Overridepublic void setTv(ITV3 itv3) {this.itv3 itv3;}Overridepublic void open() {this.itv3.play();}
}结
底层模块尽量都要有抽象类或接口或者两者都有程序稳定性更好变量的声明类型尽量是抽象类或接口这样我们的变量引用和实际对象间就存在一个缓冲层利于程序扩展和优化继承时遵循里氏替换原则什么是里氏替换原则下次讲 关注我共同进步每周至少一更。——Wayne