面向对象的7种设计原则(3)-依赖倒置原则

依赖倒置原则

  • 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,于是他买了一本《Java从入门到放弃》

class Runtu {

    public void study(Java java){
        java.bookName();
    }
}

class Java{
    public void bookName(){
        System.out.println("《Java从入门到放弃》");
    }
}

class Program{
    public static void main(String[] args) {
        Runtu runtu = new Runtu();
        Java java =new Java();
        runtu.study(java);
    }
}

过了一段时间,闰土java学完了,又想学习一下《Linux从删库到跑路》

class Runtu {

    public void study(Java java) {
        java.bookName();
    }

    public void study(Linux linux) {
        linux.bookName();
    }
}

class Java {
    public void bookName() {
        System.out.println("《Java从入门到放弃》");
    }
}

class Linux {
    public void bookName() {
        System.out.println("《Linux从删库到跑路》");
    }
}

class Program {
    public static void main(String[] args) {
        Runtu runtu = new Runtu();
        Java java = new Java();
        Linux linux = new Linux();
        runtu.study(java);
        runtu.study(linux);
    }
}

闰土除了抓猹看西瓜地外,学习新技术也很快,很快这2本都学完了。听说前端的Vue很火,梦想成为一个看西瓜的人中技术最好的仔的闰土就又买了一本《Vue从入门到崩溃》,如果继续按上面的模式,随着闰土的不断学习,我们的代码却越来越臃肿,变得难以维护。
由于RunTu是一个高级模块并且是一个细节实现类,此类依赖了书籍Java和Linux又是一个细节依赖类,这导致RunTu每读一本书都需要修改代码,这与我们的依赖倒置原则是相悖的。
闰土也意识到了这一点,买了一本《设计模式》看了看,然后改成了下边的代码:

class Runtu {

     void study(IBook iBook) {
         iBook.bookName();
    }
}

abstract class IBook{
    abstract void bookName();
}

class Java extends IBook{
     void bookName() {
        System.out.println("《Java从入门到放弃》");
    }
}

class Linux extends IBook{
     void bookName() {
        System.out.println("《Linux从删库到跑路》");
    }
}

class Program {
    public static void main(String[] args) {
        Runtu runtu = new Runtu();
        Java java = new Java();
        Linux linux = new Linux();
        runtu.study(java);
        runtu.study(linux);
    }
}

我们发现,只要让RunTu依赖于抽象IBook,其他书籍依赖于该抽象,以后不管闰土读什么书,都不会放弃跑路了。

依赖关系传递的三种方式

通过接口和抽象类传递

class Runtu {

     void study(IBook iBook) {
         iBook.bookName();
    }
}

通过构造方法传递

class Runtu {
     private IBook iBook;

    public Runtu(IBook iBook) {
        this.iBook = iBook;
    }

    void study() {
         this.iBook.bookName();
    }
}

通过Setter方法传递

class Runtu {
     private IBook iBook;

    public void setiBook(IBook iBook) {
        this.iBook = iBook;
    }

    void study() {
         this.iBook.bookName();
    }
}

总结

依赖倒置原则的本质就是通过抽象(接口或抽象类)使各个类或模块的实现彼此独立,不互相影响,实现模块间的松耦合。我们在项目中使用这个原则要遵循下面的规则:

  • 每个类尽量都有接口或者抽象类,或者抽象类和接口两都具备

  • 变量的表面类型尽量是接口或者抽象类

  • 任何类都不应该从具体类派生

  • 尽量不要覆写基类的方法

  • 如果基类是一个抽象类,而这个方法已经实现了,子类尽量不要覆写。类间依赖的是抽象,覆写了抽象方法,对依赖的稳定性会有一定的影响

个人博客
腾讯云社区
掘金
CSDN
简书
GitHub
码云
OSCHINA
Segmentfault
公众号:wx.jpg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
面向对象编程依赖倒置原则(DIP)是指高层模块不应该依赖底层模块,它们应该依赖于抽象接口。抽象接口不应该依赖于具体实现,具体实现应该依赖于抽象接口。 依赖倒置原则的核心思想是:针对接口编程,而不是针对实现编程。在实际编程,应该将底层模块的具体实现隔离出来,通过抽象接口来定义高层模块与底层模块的交互方式。这样可以使得代码更加灵活、可扩展、容易维护和测试。 举个例子,假设我们有一个电子商务系统,它包含了用户管理、订单管理和商品管理等功能模块。如果我们没有遵守依赖倒置原则,那么这些模块之间的依赖关系可能会是这样的: ![依赖倒置原则示例1](https://cdn.jsdelivr.net/gh/YunboCheng/picgo-pic-bed/img/20211020095420.png) 可以看到,高层模块依赖于底层模块的具体实现,这样会导致代码的耦合度很高,如果其一个模块发生了变化,其他模块也需要进行修改。 如果我们遵守依赖倒置原则,代码的结构可能会变成这样: ![依赖倒置原则示例2](https://cdn.jsdelivr.net/gh/YunboCheng/picgo-pic-bed/img/20211020095522.png) 可以看到,高层模块不再依赖于底层模块的具体实现,而是依赖于抽象接口,这样就可以实现高层模块与底层模块的解耦。如果其一个模块发生了变化,只需要修改它自己的实现,而不会影响其他模块。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值