写点什么

依赖倒置原则 & 接口隔离原则优化 Cache 类

用户头像
高程
关注
发布于: 2020 年 06 月 17 日

一、依赖倒置原则

问题一:什么是依赖倒置原则?

依赖倒置原则的含义

依赖倒置原则(Dependence Inversion Principle,简称DIP。其含义分为三层:

  • 模块间的依赖是通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的;

  • 接口或抽象类不依赖于实现类;

  • 实现类依赖接口或抽象类。

ps:书读百遍,其义自见。

依赖的具体写法

  1. 在接口的方法中声明依赖对象。该方法也叫做接口注入。

// 抽象接口设计
public interface IDriver {
//是司机就应该会驾驶汽车
public void drive(ICar car);
}
// 实现类实现
public class Driver implements IDriver{
//司机的主要职责就是驾驶汽车
public void drive(ICar car){
car.run();
}
}



  1. 构造函数传递依赖对象。在类中通过构造函数声明依赖对象,按照依赖注入的说法这种方式叫做构造函数注入。

// 抽象接口设计
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();
}
}



  1. Setter方法传递依赖对象。在抽象中设置setter方法声明依赖关系,依照依赖注入的说法就是setter依赖注入。

// 抽象接口设计
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();
}
}

问题二: 为什么有时候依赖倒置原则又被称为好莱坞原则?

好莱坞原则含义:

在好莱坞,把简历递交给演艺公司后就只有回家等待。由演艺公司对整个娱乐项的完全控制,演员只能被动式的接受公司的差使,在需要的环节中,完成自己的演出。

两者的关系:

低层次模块实现了高层次模块的接口,然后总是被高层次模块调用。

案例:

错误的依赖关系

public class Dao {
private MysqlConnection connection;
public Dao(MysqlConnection connection) {
this.connection = connection;
}
public void findAll() {
connection.executeQuery("SELECT * FROM test");
}
}
public class MysqlConnection {
public void executeQuery(String sql) {
System.out.println(sql);
}
}

Dao类通过调用MysqlConnection类的executeQuery方法执行sql语句,依赖关系如下图所示:

这里就违反了依赖倒置原则,高层模块DAO强耦合了底层模块MysqlConnection。如果系统需要更换数据库为SqlServer,我们就不得不去修改Dao类,增加一个SqlserverConnection类,这又违反了面向对象设计的开闭原则。例子中的Dao是一个不稳定、随时会因为底层模块的变更而出现BUG的类。

正确的依赖关系

public class Dao {
private Connection connection;
public Dao(Connection connection) {
this.connection = connection;
}
public void findAll() {
connection.executeQuery("SELECT * FROM test");
}
}
public interface Connection {
void executeQuery(String sql);
}
public class MysqlConnection implements Connection {
@Override
public void executeQuery(String sql) {
System.out.println(sql);
}
}



Dao类通过调用Connection接口的executeQuery方法执行sql语句,依赖关系如下图所示:

修改后的Dao类依赖于Connection抽象接口,MysqlConnection类也以实现接口的方式依赖于Dao类。这时如果要更换为SqlServer数据库,只要增加一个SqlserverConnection类并实现Connection接口就完成了,不需要去修改Dao类了,大大的降低了耦合度。



二、 框架中,依赖导致的实现

php: Laravel中的容器,golang中也涉及到过,忘记了,后续补充吧……

用户头像

高程

关注

还未添加个人签名 2018.08.07 加入

还未添加个人简介

评论

发布
暂无评论
依赖倒置原则&接口隔离原则优化Cache类