06. 依赖倒置原则介绍
06.依赖倒置原则介绍
目录介绍
01.问题思考的分析
02.学习依赖倒置目标
03.理解依赖倒置原则
04.依赖倒置原则思想
05.多数据库操作案例
06.用户购买家电案例
07.发送消息的案例
08.依赖倒置 VS 依赖注入
09.依赖倒置的思考
10.依赖倒置原则总结
推荐一个好玩网站
一个最纯粹的技术分享网站,打造精品技术编程专栏!编程进阶网
设计模式 Git 项目地址:https://github.com/yangchong211/YCDesignBlog
简介: 依赖倒置原则是面向对象设计六大原则之一,强调高层模块不应依赖低层模块,两者应依赖于抽象。通过依赖接口或抽象类而非具体实现,降低模块耦合度,提升系统灵活性和可维护性。本文详解该原则的概念、目标、思想及其实现方式(如依赖注入),并结合多数据库操作、用户购买家电、发送消息等实际案例,深入探讨其应用与优缺点。
01.问题思考的分析
依赖倒置原则。单一职责原则和开闭原则的原理比较简单,但是,想要在实践中用好却比较难。而今天要讲到的依赖倒置原则正好相反。
这个原则用起来比较简单,但概念理解起来比较难。比如,下面这几个问题,你看看能否清晰地回答出来:
“依赖倒置”这个概念指的是“谁跟谁”的“什么依赖”被反转了?“倒置”两个字该如何理解?
经常听到另外一个概念:依赖注入。这两个概念跟“依赖倒置”有什么区别和联系呢?它们说的是同一个事情吗?
02.学习依赖倒置目标
搞懂依赖倒置原则,为什么依赖倒置是重要的,以及它如何帮助我们构建灵活、可扩展和可维护的软件系统。
掌握依赖倒置的实现方式,依赖注入、工厂模式、策略模式等常见的实现方式,以及它们的优缺点和适用场景。
应用依赖倒置到实际项目:通过实际项目的练习和实践,将依赖倒置应用到实际的软件开发中。
03.理解依赖倒置原则
依赖倒置原则是面向对象设计的六大原则之一,它的定义是:
高层模块不应该依赖于低层模块。两者都应该依赖于抽象。
抽象不应该依赖于细节。细节应该依赖于抽象。
换句话说,设计中应当依赖于接口或抽象类,而不是依赖于具体实现。这种设计有助于减少模块之间的耦合,增加系统的灵活性和可维护性。
04.依赖倒置原则思想
依赖倒置原则的核心思想是面向抽象编程而不是面向具体编程。通过依赖抽象层次(如接口、抽象类),可以让高层模块不依赖具体的实现细节,从而使得系统更具扩展性和灵活性。
05.多数据库操作案例
例子 1:违反依赖倒置原则。假设我们有一个 UserService 类,它直接依赖于 MySQLDatabase 类来进行数据操作。
在这个例子中,UserService 类直接依赖于 MySQLDatabase 类,这是对具体实现的依赖,违反了依赖倒置原则。
如果我们需要将数据库换成 PostgresSQLDatabase,或者换成 AliSQLDatabase,我们必须修改 UserService 类,这增加了系统的耦合度和修改的风险。
例子 2:遵循依赖倒置原则。可以通过引入一个抽象层来遵循依赖倒置原则。
在这个例子中,UserService 类依赖于 Database 接口,而不是具体的数据库实现。
这意味着如果我们想更换数据库,只需要传入不同的实现类,而不需要修改 UserService 类本身。这样做遵循了依赖倒置原则,降低了模块之间的耦合度。
从这个例子可知,定义数据库抽象层供不同的数据库实现,然后在 UserService 类依赖于抽象接口而不是具体实现,可以充分降低代码耦合度,可以快速拓展其他数据库实现。
06.用户购买家电案例
例子 1:违反依赖倒置原则。假设顾客,想要买冰箱,洗衣机,电视,或者其他电器,它直接依赖于 Customer 类来进行数据操作。
例子 2:遵循依赖倒置原则。可以通过引入一个抽象层来遵循依赖倒置原则。
07.发送消息的案例
例子 1:违反依赖倒置原则。假设用户,可以通过邮件,短信息,信件等发送消息,下面这种就不太友好。
例子 2:遵循依赖倒置原则。可以通过引入一个抽象层来遵循依赖倒置原则。
08.依赖倒置 VS 依赖注入
8.1 理解依赖注入
依赖注入(Dependency Injection, DI)是一种设计模式,旨在将对象的依赖关系从对象内部转移到外部管理,从而降低类之间的耦合度,提高代码的可维护性和可测试性。
8.2 依赖注入方式
依赖注入(Dependency Injection,DI)是一种通过将依赖关系从高层模块解耦的方式,常用于实现依赖倒置原则。
构造函数注入:通过在类的构造函数中声明依赖参数,将依赖关系通过构造函数传递给类的实例。最常见的依赖注入方式。
Setter 方法注入:通过提供一组 setter 方法,允许外部代码设置依赖对象。这种方式相对于构造函数注入更灵活,可以在对象创建后随时更改依赖。
接口注入:通过在类中定义一个接口,该接口包含用于注入依赖的方法。类实现该接口,并通过接口方法接收依赖对象。这种方式相对较少使用,因为它引入了更多的接口和方法。
属性注入:通过在类中声明依赖对象的属性,并提供相应的 setter 方法,将依赖对象注入到属性中。可能导致类的实例在没有依赖对象的情况下被创建。
8.3 两者有何区别
依赖倒置原则(Dependency Inversion Principle,DIP)和依赖注入(Dependency Injection,DI)是面向对象设计中两个相关但不同的概念。
依赖倒置原则是一种设计原则,它指导我们在设计软件时应该依赖于抽象而不是具体实现。高层模块不应该直接依赖于低层模块,而是通过抽象接口或基类来进行依赖。
依赖注入是一种实现依赖倒置原则的具体技术,它通过将依赖关系从高层模块解耦,将依赖对象注入到类的实例中。依赖注入有多种方式,如构造函数注入、setter 方法注入、属性注入等。它的目的是通过外部注入依赖对象,而不是在类内部创建或获取依赖对象。
依赖注入是实现依赖倒置原则的一种常见方式,但并不是唯一的方式。依赖倒置原则还可以通过工厂模式、策略模式等其他设计模式来实现。
09.依赖倒置的思考
9.1 依赖倒置优点
降低耦合性:高层模块和低层模块之间通过抽象进行解耦,避免了对具体实现的依赖。
增强可扩展性:通过依赖抽象,可以更容易地替换或扩展具体实现,而不需要修改高层模块。
提高可维护性:模块之间的解耦使得系统的维护变得更加容易,修改一个模块的实现不会影响到其他模块。
9.2 依赖倒置缺点
增加系统的复杂性:为了遵循依赖倒置原则,通常需要引入额外的抽象层次,这可能会增加系统的复杂性。
可能导致过度设计:在简单系统中,如果过度使用依赖倒置原则,可能导致不必要的复杂性,造成过度设计。
9.3 在设计模式的体现
工厂模式(Factory Pattern):通过定义抽象工厂接口,让具体的工厂类实现该接口,从而将对象的创建过程与使用过程解耦。这样,高层模块只依赖于抽象工厂接口,而不依赖于具体的产品类。这符合依赖倒置原则,使得高层模块依赖于抽象而非具体实现。
观察者模式(Observer Pattern):观察者依赖于被观察者的抽象接口,而不依赖于具体的被观察者。这样,当被观察者发生变化时,观察者可以接收到通知并做出相应的处理,而不需要直接依赖于具体的被观察者。
策略模式(Strategy Pattern):通过定义一个抽象策略接口,让具体的策略类实现该接口,从而将算法的选择与使用解耦。高层模块通过依赖于抽象策略接口,而不依赖于具体的策略类,实现了依赖倒置原则。
这些设计模式的共同点是,它们都通过引入抽象接口或基类,将高层模块与具体实现解耦,使得高层模块依赖于抽象而非具体实现。符合依赖倒置原则的设计思想。
10.依赖倒置原则总结
依赖倒置问题思考:“依赖倒置”这个概念指的是“谁跟谁”的“什么依赖”被反转了?“倒置”两个字该如何理解?
学习该原则目标:搞懂该原则作用,掌握实现方式,并且应用到实际案例项目中。
依赖倒置的定义:高层模块不应该依赖底层模块,应该依赖于抽象。换句话说,设计中应当依赖于接口或抽象类,而不是依赖于具体实现。
依赖倒置原则思想:通过依赖抽象层次(如接口、抽象类),可以让高层模块不依赖具体的实现细节,从而使得系统更具扩展性和灵活性。
多数据库操作案例:从这个例子可知,定义数据库抽象层供不同的数据库实现,然后在 UserService 类依赖于抽象接口而不是具体实现,可以充分降低代码耦合度,可以快速拓展其他数据库实现。
依赖注入如何理解:依赖注入(Dependency Injection,DI)是一种通过将依赖关系从高层模块解耦的方式,常用于实现依赖倒置原则。
依赖注入有哪些方式:1.构造函数注入;2.Setter 方法注入;3.接口注入;4.属性注入
依赖倒置和依赖注入区别:依赖倒置原则是一种设计原则,依赖注入是一种实现依赖倒置原则的具体技术。
依赖倒置有哪些缺点:为了遵循依赖倒置原则,通常需要引入额外的抽象层次,这可能会增加系统的复杂性。
在设计模式的体现有哪些:工厂模式,观察者模式,策略模式,这些设计模式的共同点是,它们都通过引入抽象接口或基类,将高层模块与具体实现解耦,使得高层模块依赖于抽象而非具体实现。符合依赖倒置原则的设计思想。
11.更多内容推荐
版权声明: 本文为 InfoQ 作者【杨充】的原创文章。
原文链接:【http://xie.infoq.cn/article/d237ba3dae03a0cb7c34d3584】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论