DIP依赖倒置原则

发布于:2025-05-13 ⋅ 阅读:(20) ⋅ 点赞:(0)

DIP强调在应用中,高层模块不应该依赖低层模块,两者都应该依赖抽象;抽象不应该依赖细节,细节应该依赖抽象。源代码依赖方向与控制流方向的反转,这是DIP被称为依赖反转的原因。DIP指导跨越架构边界。

DIP特点

  • 降低耦合度:高层模块和低层模块之间的依赖关系通过抽象接口来实现,降低了直接依赖关系。
  • 提高扩展性:低层模块的实现可以灵活替换,只要遵循抽象接口的规范即可。
  • 便于测试:高层模块可以通过依赖注入等方式使用模拟对象(Mock)进行测试,而不依赖低层模块。

示例代码

不符合DIP的代码

class EmailSender {
    public void send(String message) {
        // 具体的邮件发送逻辑
    }
}

class MessageService {
    private EmailSender emailSender;

    public MessageService() {
        this.emailSender = new EmailSender();
    }

    public void sendMessage(String message) {
        emailSender.send(message);
    }
}

使用DIP优化后的代码

// 抽象接口
interface MessageSender {
    void send(String message);
}

// 具体实现
class EmailSender implements MessageSender {
    @Override
    public void send(String message) {
        // 具体的邮件发送逻辑
    }
}

class SmsSender implements MessageSender {
    @Override
    public void send(String message) {
        // 具体的短信发送逻辑
    }
}

// 高层模块
class MessageService {
    private MessageSender messageSender;

    public MessageService(MessageSender messageSender) {
        this.messageSender = messageSender;
    }

    public void sendMessage(String message) {
        messageSender.send(message);
    }
}

注意点

抽象优先
在设计初期定义抽象接口,避免先实现具体类再抽取接口。

使用依赖注入(DI)
通过构造器、Setter 方法或依赖注入框架(如 Spring)注入依赖。

避免在高层模块中实例化具体类
将对象创建逻辑封装在工厂类或配置文件中。

依赖注入框架的应用
在大型项目中使用 DI 框架(如 Spring)管理对象依赖关系。

不要在具体实现类上创建衍生类。

不要覆盖包含具体实现的函数。

避免在代码中写入任何具体实现相关的名字,或者是其他容易变动的事物的名字。

参考

《架构整洁之道》-- Robert C.Mattin

《架构师的自我修炼》 – 李智慧

《设计模式之美》 – 王争


网站公告

今日签到

点亮在社区的每一天
去签到