Bootstrap

依赖倒置原则和接口隔离示例

依赖倒置原则 DIP, Dependency Inversion Principle

  • 高层模块不能依赖底层模块,而是大家都依赖于抽象;

  • 抽象不能依赖实现,而是实现依赖抽象

DIP 倒置了模块或包的依赖关系,开发顺序和职责。

高层决定低层:高层模块定义(依赖)一个接口,供底层模块来实现。

高层被重用:高层被重用的可能更大

面向抽象编程,关键的问题在于抽闲属于谁

好莱坞规则:Don’t Call me, I will Call you.

我的理解(想象),但是好莱坞有很多的演员,类似于北漂,因为人多,所以制片人说,不要给我打电话,如果需要我来找你。

Tomcat 基于规范或者 Servlet 接口开发。高层模块不依赖低层模块,框架不依赖与实现代码,而是依赖于接口,框架可以调用代码。

Button 的本质:检测用户的按键指令,传递给目标对象。

用什么机制检测用户的按键,目标对象是什么,都不重要。

最早学到 SOLID 原则的时候,感觉依赖倒置原则是最难理解的,不过专栏的开篇就说,其实 Spring、Tomcat 这些框架都是依赖倒置,感觉一下子就捅破了窗户纸。

实现了一下文中提到的开灯的例子。

public interface ButtonServer {
     void turnOn();
     void turnOff();
}

class Lamp implements ButtonServer {
    public void turnOn() {
        System.out.println("Lamp On");
    }

    public void turnOff() {
        System.out.println("Lamp Off");
    }
}

class Button {
    ButtonServer bs;
    public void Button(ButtonServer buttonServer) {
        bs = buttonServer;
    }
    public void poll() {
        bs.turnOff();
        bs.turnOn();
    }
}

有一个小的疑问,本节中的 ButtonServer 中定义了两个方法 turnOn() 和 turnOff(),那么和上一节中策略模式里面 ButtonServer 中定义 buttonPressed(int token) 方法是不是有重叠的部分,我的意思是,本节中的 ButtonServer 是否也算是策略模式?

两个示意图中从 Button 指向 ButtonServer 的箭头不同,但是这个并不是决定因素。

很多人提到 MVC 模式违背了依赖倒置原则,我有点疑惑,可能是因为写法的不同。如果是从数据访问开始写,当然是违背了依赖倒置,但是如果是从建领域模型开始,那么很容易做到依赖倒置。

按照接口隔离原则,将 Cache 中的方法分为两个接口,CacheManageable 和 Cacheable,如下图。

类似于 Cache 这种,如果因为考虑到把相关的方法和属性都放在一个类里面(单一职责原则),但是有不想给客户端暴露无关的方法,那么就可以多隔离出来几个接口。