目录
1.构造函数传递依赖对象在类中通过构造函数声明依赖对象,按照依赖注入的说法,这种方式叫做构造函数注入,按照这种方式的注入,对IDriver和Driver进行修改。
最近准备把自己对于面向对象六大设计原则的学习心得进行梳理记录一下,以备后面查看。
单一职责原则(Single Responsibility Principle):一个类应该只有一个引起变化的原因。这意味着一个类应该只负责一项功能或职责,这样当需求变化时,只需要修改或扩展这个类,而不需要修改它的原有代码。
开放封闭原则(Open Close Principle):软件实体应该对扩展开放,对修改封闭。这意味着当软件需要适应新的需求时,应该通过添加新的代码来扩展系统的行为,而不是修改已有的代码。
里氏替换原则(Liskov Substitution Principle):子类型必须能够替换其基类型。这意味着在软件中,如果使用基类型的地方都可以使用子类型,那么这个子类型就应该符合基类型的行为约定。
接口隔离原则(Interface Segregation Principle):客户端不应该依赖于它不使用的接口。这意味着接口应该小而专一,只提供客户端需要的方法,而不是提供一个庞大的接口让客户端依赖它不需要的方法。
依赖倒置原则(Dependency Inversion Principle):高层模块不应该依赖于低层模块的具体实现,而应该依赖于抽象。这意味着应该通过抽象(如接口或抽象类)来建立模块之间的依赖关系,从而降低耦合度。
迪米特法则(Law of Demeter):一个对象应该对其朋友使用的对象知道得最少。这表明一个对象应该尽可能少地了解其直接朋友(直接调用它的对象)之外的其它对象,以减少对象之间的耦合。
Dependence Inversion Principle,DIP(依赖倒置)
High level modules should not depend upon low level modules. Both should depend upon abstractions. (高层模块不应该依赖底层模块,两者都应该依赖抽象)
每一个逻辑的实现都是由原子逻辑组成的,不可分割的原子逻辑就是低层模块,原子逻辑的再组装就是高层模块(示例图如下图所示)
Abstractions should not depend upon details.(抽象不应该依赖于细节)
Details should depend upon abstractions (细节应该依赖于抽象)
但是根据依赖倒置原则,上图中的实现应该调整为
在Java语言中,抽象就是指接口或抽象类,两者都是不能直接被实例化的;细节就是实现类,实现接口或继承抽象类而产生的类就是细节,其特点就是可以直接被实例化。
简单来说,核心思想就是**针对接口编程,不要针对实现编程。**把容易变换的部分,抽象成接口,以便于后续扩展。
相对于细节的多变性,科学合理的抽象要稳定的多。以抽象为基础搭建起来的架构比以细节为基础搭建起来的架构要稳定的多。在大多数软件设计中,抽象是指接口或抽象类,细节就是实现了接口或继承了抽象类的子类,使用接口或者抽象类的目的是定制好规范和契约,而不去涉及任何具体操作,把细节的展现任务交给他们的子类去实现。
尽可能的制定良好的抽象、接口规范,如果类之间如果要发生依赖,那么依赖于抽象接口更加稳定且利于扩展。
● 模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的;
● 接口或抽象类不依赖于实现类;
● 实现类依赖接口或抽象类。
采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读性和可维护性。
不同的产品依赖于接口,不同的工厂依赖统一的接口
观察者依赖于统一接口,实现了update通知方法,提供被通知的行为
不同的状态类依赖于统一的接口,实现了接口中抽象的共同行为,等待被传递及调用其他模式中的接口
看到很多文章中有很好的示例,本文就不重复说明。
面向对象五大设计原则-依赖倒置原则_依赖倒置原则的案例-CSDN博客 (通过手机模块设计来讲解依赖倒置,无代码实现)
使用以下5个例子,来说明依赖倒置(具体内容见上文链接)
设计模式—— 三:依赖倒置原则_java倒置依赖的写法-CSDN博客
里面关于
依赖是可以传递的,A对象依赖B对象,B又依赖C,C又依赖D——只要做到抽象依赖,即使是多层的依赖传递也是没有丝毫问题的。
对象的依赖关系有三种方式来传递,如下所示:
1.构造函数传递依赖对象
在类中通过构造函数声明依赖对象,按照依赖注入的说法,这种方式叫做构造函数注入,按照这种方式的注入,对IDriver和Driver进行修改。
public interface IDriver {
//司机就会开车
public void drive();
}
public class Driver implements IDriver{
private ICar car;
//构造函数注入
public Driver(ICar _car){
this.car = _car;
}
//司机的主要职责就是驾驶汽车
public void drive(){
this.car.run();
}
}
在抽象中设置Setter方法声明依赖关系,依照依赖注入的说法,这是Setter依赖注入,按照这种方式的注入,对IDriver和Driver进行修改:
public interface IDriver {
//车辆型号
public void setCar(ICar car);
//是司机就应该会驾驶汽车
public void drive();
}
public class Driver implements IDriver{
private ICar car;
public void setCar(ICar car){
this.car = car;
}
//司机的主要职责就是驾驶汽车
public void drive(){
this.car.run();
}
}
在接口的方法中声明依赖对象,未修改的IDriver和Driver就采用了接口声明依赖的方式,该方法也叫做接口注入。
public interface IDriver {
//老司机,会开车
public void drive(ICar car);
}
public class Driver implements IDriver{
//司机的主要职责就是驾驶汽车
public void drive(ICar car){
car.run();
}
}