C# 依赖倒置原则(DIP)

article/2025/9/22 23:19:00

目录

一,引子

1.1 传统的程序架构

1.2 依赖倒置

1.3 依赖倒置的作用

二,依赖注入


一,引子

1.1 传统的程序架构

在程序执行过程中,传统的程序架构如图:

可以看到,在传统的三层架构中,层与层之间是相互依赖的,UI层依赖于BLL层,BLL层依赖于DAL层。分层的目的是为了实现“高内聚、低耦合”。传统的三层架构只有高内聚没有低耦合,层与层之间是一种强依赖的关系,这也是传统三层架构的一种缺点。这种自上而下的依赖关系会导致级联修改,如果低层发生变化,可能上面所有的层都需要去修改,而且这种传统的三层架构也很难实现团队的协同开发,因为上层功能取决于下层功能的实现,下面功能如果没有开发完成,则上层功能也无法进行。

1.2 依赖倒置

依赖倒置(DIP):Dependence Inversion Principle的缩写,是一种软件架构设计的原则(抽象概念)。依赖于抽象不依赖于细节。主要有两层含义:

  1. 高层次的模块不应该依赖低层次的模块,两者都应该依赖其抽象。
  2. 抽象不应该依赖于具体,具体应该依赖于抽象。

如何理解这两句话?

  • 第一句话:模块之间的依赖是通过抽象发生的,实现类之间不应该发生直接的依赖关系,他们的依赖关系应该通过接口或者抽象类产生。
  • 第二句话:举个例子,假如我们要写BLL层的代码,直接就去实现了功能,等到开发完成以后发现没有使用依赖倒置原则,这时候在根据实现类去写接口,这种是不对的,应该首先设计抽象,然后在根据抽象去实现,应该要面向接口编程。

 根据依赖倒置原则重新设计代码执行架构:

UI、BLL、DAL三层之间应该没有直接的依赖关系,都应该依赖于接口。首先应该先确定出接口,DAL层抽象出IDAL接口,BLL层抽象出IBLL接口,这样UI层依赖于IBLL接口,BLL实现IBLL接口。BLL层依赖于IDAL接口,DAL实现IDAL接口。如下图所示:

1.3 依赖倒置的作用

有了依赖倒置原则,可以使我们的架构更加的稳定、灵活,也能更好地应对需求的变化。相对于细节的多变性,抽象的东西是稳定的。所以以抽象为基础搭建起来的架构要比以细节为基础搭建起来的架构要稳定的多。

在传统的三层架构里面,仅仅增加一个接口层,我们就实现了依赖倒置,目的就是降低层与层之间的耦合。有了这样的接口层,三层架构才真正实现了“高内聚、低耦合”的思想。

二,依赖注入

依赖倒置原则是架构层面上的,那么如何在代码层面上实现呢?这就需要用到控制反转IOC

传统开发,上端依赖(调用/指定)下端对象,会有依赖,把对下端对象的依赖转移到第三方容器(工厂+配置文件+反射),能够程序拥有更好的扩展性,是DIP的具体实现方式,可以用来减低计算机代码之间的耦合度。

依赖注入DI 是控制反转的一种实现方式。

  1. 是实现IOC的手段和方法,就是能做到构造某个对象时,将依赖的对象自动初始化并注入 :
  2. 有三种注入方式:构造函数注入--属性注入--方法注入(按时间顺序):
  3. 构造函数注入用的最多,默认找参数最多的构造函数,可以不用特性,可以去掉对容器的依赖

下面通过一个例子,对上述专业名词进行解释:

父亲给孩子讲故事,只要给这个父亲一本书,他就可以照着这本书给孩子讲故事。

  • 我们下面先用最传统的方式实现一下,这里不使用任何的设计原则和设计模式。

首先定义一个Book类:

 public class Book{public string GetContent(){return "门前大桥下,游过一群鸭";}}

然后定义父亲Father类:

 public class Father{public void read(){Book book = new Book();Console.WriteLine("爸爸开始给孩子讲故事了:");Console.WriteLine(book.GetContent());}}

主程序调用:

  static void Main(string[] args){Father father = new Father();father.read();Console.ReadKey();}
//打印效果:
爸爸开始给孩子讲故事了:
门前大桥下,游过一群鸭

 我们来看看关系图:

可以看到:Father是直接依赖于Book类。

这时需求发生了变化,不给爸爸书了,给爸爸报纸,让爸爸照着报纸给孩子读报纸,这时该怎么做呢?按照传统的方式,我们这时候需要再定义一个报纸类,还要修改Father类。

但是需求在不断的变化,不管怎么变化,对于爸爸来说,他一直在读读物,但是具体读什么读物是会发生变化,这就是细节,也就是说细节会发生变化。但是抽象是不会变的。如果这时候还是使用传统的OOP思想来解决问题,那么会导致程序不断的在修改。

下面使用工厂模式来优化:

首先创建一个接口:

 public interface IReader{string GetContent();}

然后让Book类和NewsPaper类都继承自IReader接口

    public class Book:IReader{public string GetContent(){return "门前大桥下,游过一群鸭";}}public class NewsPaper : IReader{public string GetContent(){return "7月3日是地球上有记录以来最热的一天";}}

 之后创建一个工厂类:

public static class ReaderFactory{public static IReader GetReader(string readerType){if (string.IsNullOrEmpty(readerType)){return null;}switch(readerType){case "NewsPaper":return new NewsPaper();case "Book":return new Book();default:return null;}}}

里面方法的返回值是一个接口类型。最后在Father类里面调用工厂类:

public class Father{private IReader reader { get; set; }public Father(string readerName){reader = ReaderFactory.GetReader(readerName);}public void read(){Console.WriteLine("爸爸开始给孩子讲故事了:");Console.WriteLine(reader.GetContent());}}

 最后在主程序调用:

 static void Main(string[] args){Father father = new Father("NewsPaper");father.read();Console.ReadKey();}
//打印效果:
爸爸开始给孩子讲故事了:
7月3日是地球上有记录以来最热的一天

此时的依赖关系图:

这时Father已经和Book、Paper没有任何依赖了,Father依赖于IReader接口,还依赖于工厂类,而工厂类又依赖于Book和Paper类。这里实际上已经实现了控制反转。Father(高层)不依赖于低层(Book、Paper)而是依赖于抽象(IReader),而且具体的实现也不是由高层来创建,而是由第三方来创建(这里是工厂类)。但是这里只是使用工厂模式来模拟控制反转,而没有实现依赖的注入,依赖还是需要向工厂去请求。

再进一步优化代码 

 

 由于此时没有了工厂,我们还是需要在主程序调用中实例化具体的实现类。


http://chatgpt.dhexx.cn/article/8l4Jw3UW.shtml

相关文章

设计模式-依赖倒置原则

依赖倒置原则 1 依赖倒置原则的定义 依赖倒置原则(Dependence Inversion Principle,DIP)这个名字看着有点别扭,“依赖”还“倒置”,这到底是什么意思?依赖倒置原则的原始定义是: High level modules shou…

C++ 依赖倒置原则

.依赖倒置原则 定义 高层模块不应该依赖于底层模块,而应该依赖于抽象。抽象不应依赖于细节,细节应依赖于抽象。解决的问题 类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般…

【设计原则】依赖倒置原则 (面向接口编程)

本文将以Java为基础,讲解开发中,面向接口编程的知识,只要以简单的例子为主,讲解如何进行面向接口编程,并会区分其于面向实现编程的区别。下面先讲一讲依赖倒置原则,再过渡到案例解释。 本文目的在于用极其简单的图解帮…

设计模式 — 6大设计原则(依赖倒置和接口隔离原则)

设计模式 依赖倒置原则示例 一示例 二依赖的三种写法总结 接口隔离原则实例 一总结 依赖倒置原则 依赖倒置原则(Dependence Inversion Principle,DIP)这个名字看着有点别扭,“依赖” 还 “倒置” ,这到底是什么意思&a…

【六大设计原则-SOLID】

SOLID简介: 历史:由Robert CMartin汇总并推广 目标: 使软件更容易被改动是软件更容易被理解构建可以在多个软件系统中复用的组件 组成: 名称简写含义单一职责原则 SRP Single Responsibility Principle 初始定义&#xff08…

SOLID原则:解释和实例

在面向对象编程中,SOLID是5个重要的设计原则的缩写。首先是由著名的软件大师Robert C.Martin (Bob 大叔)在Design Principles and Design Patterns 中提出, 后来Michael Feathers 用SOLID来概括这五大原则。 SOLID原则使得软件设计更加容易理解、灵活和可维护。作为一名软件…

SOLID原则的含义和具体使用

单一职责原则(SRP)开放封闭原则(OCP)里氏替换原则(LSP)接口隔离原则(ISP)依赖倒置原则(DIP)小结 SOLID 是面向对象设计5大重要原则的首字母缩写,当…

设计模式:SOLID原则

单一职责原则 Single Responsibility Principle(SRP) 接口职责应该单一,不要承担过多的职责。 开放封闭原则 Open Closed Principle(OCP) 添加一个新的功能应该是,在已有代码基础上扩展代码(…

设计模式之SOLID原则

介绍 设计模式中的SOLID原则,分别是单一原则、开闭原则、里氏替换原则、接口隔离原则、依赖倒置原则。前辈们总结出来的,遵循五大原则可以使程序解决紧耦合,更加健壮。 SRP 单一责任原则 OCP …

SOLID 原则要这么理解!

什么是 SOLID 原则 SOLID 原则其实是用来指导软件设计的,它一共分为五条设计原则,分别是: 单一职责原则(SRP)开闭原则(OCP)里氏替换原则(LSP)接口隔离原则(…

SOLID 设计原则 (有点长但很透彻)

面向对象设计原则 SOLID 应该是职业程序员必须掌握的基本原则,每个程序员都应该了然于胸,遵守这 5个原则可以帮助我们写出易维护、易拓展的高内聚低耦合的代码。 它是由罗伯特C马丁(知名的 Rob 大叔)21世纪初期 (准确来说,2000年在他的论文De…

软件开发SOLID设计原则

前言:SOLID设计原则,不管是软件系统还是代码的实现,遵循SOLID设计原则,都能够有效的提高系统的灵活和可靠性,应对代码实现的需求变化也能更好的扩展和维护。因此提出了五大原则——SOLID。 我是通过老师讲解以及老师…

Python 中的 SOLID 原则

💂 个人网站:【海拥】【摸鱼游戏】【神级源码资源网】🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】💅 想寻找共同学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】 SOLID 是一组面向对象…

Kotlin SOLID 原则

Kotlin SOLID 原则 许多 Kotlin 开发者并不完全了解 SOLID 原理,即使他们知道,他们也不知道为什么要使用它。您准备好了解所有细节了吗? 介绍 亲爱的 Kotlin 爱好者,您好!欢迎来到我的新文章。今天我要讲的是 Kotli…

超易懂!原来 SOLID 原则要这么理解!

点击蓝色 “陈树义” 关注我哟 说到 SOLID 原则,相信有过几年工作经验的朋友都有个大概印象,但就是不知道它具体是什么。甚至有些工作了十几年的朋友,它们对 SOLID 原则的理解也停留在表面。今天我们就来聊聊 SOLID 原则以及它们之间的关系。…

SOLID五大原则【图解】

目录 前序 五大基本原则-SOLID 1. SRP 2. OCP 3. LSP 4. ISP 5. DIP 参考链接 前序 做C语言开发的应该都知道,C是面向过程开发的,而c是面向对象开发的。而封装、继承与多态是面向对象开发的三大特征。 但你可能不知道OOD(Object-Oriented Desi…

我所理解的SOLID原则

S.O.L.I.D 是面向对象设计(OOD)和面向对象编程(OOP)中的几个重要编码原则(Programming Priciple)的首字母缩写。 面向对象设计的原则 SRP The Single Responsibility Principle单一职责原则OCP The Open Closed Principle开放封闭原则LSP The Liskov Substitution Principle里…

浅谈 SOLID 原则的具体使用

单一职责原则(SRP)开放封闭原则(OCP)里氏替换原则(LSP)接口隔离原则(ISP)依赖倒置原则(DIP)小结 SOLID 是面向对象设计5大重要原则的首字母缩写,当…

设计模式之SOLID原则再回首

本科阶段学过设计模式,那时对设计模式的五大原则——SOLID原则的概念与理解还是比较模糊,此时过去了2年时间,在学习《高级软件工程》课程中老师又提到了设计模式,课程中还详细讨论了五大原则的过程,这次SOLID原则再回首作者提出了一些更通俗的理解吧~ 一. 什么是设计模式&…

程序设计原则之SOLID原则

设计模式中的SOLID原则,分别是单一原则、开闭原则、里氏替换原则、接口隔离原则、依赖倒置原则。前辈们总结出来的,遵循五大原则可以使程序解决紧耦合,更加健壮。 SOLID原则是由5个设计原则组成,SOLID对应每个原则英文字母的开头…