女朋友强依赖我!我引入IOC后,从此我们的关系微妙而稳固!

17f1279e0d7ba38e65c327a1777d54c9.gif

此文从面向对象设计角度分析依赖倒置原则,引入依赖注入,IOC相关内容进行探讨,文中引用女朋友案例可能引起分手风险,故理解为 new 对象。

想起在学校的时候,有一个任务就是设计一款宠物商店项目。那时候引入三层架构设计概念,分为UI(表现层)、BLL(业务逻辑层),DAL(数据访问层)。

c284cc8de622219344b8c5f3d1f8e768.png

▲图/ 简单三层架构示例

每一层各司其职,表现层只管负责用户的界面交互;业务逻辑层只管计算、验证,业务规则等等;数据访问层则负责与数据库的增、删、改,查。

设计完交差后,就会思考,为啥要使用这个,能给我带来什么好处。学完面向对象设计思想之后得出了答案,当时判定程序的良好基本可以通过“高内聚,低耦合”的方式。

确实,三层架构设计能够符合程序的高内聚,达到解耦的目的,但是并没有达到低耦合的层级,自上而下层层依赖,其耦合性还是相对较高。或许当时设计的项目相对较简单,没有直接体现出来。

工作之后才发现,三层架构设计的应用还是相对较广,曾经就有一些项目运用三层架构之后,不断的需求变更导致一层的改动,都会造成联级改动。

如果要解决这个问题,面向对象设计中有一个设计原则,就是依赖倒置原则(DIP)。

高层模块不应该依赖低层模块,两者都应依赖于抽象层。

抽象层不应该依赖于实现,实现应该依赖于抽象。

模块间的依赖通过抽象发生的,实现类之间不发生直接的依赖关系,依赖关系是通过接口或者抽象类产生的。

这个原则听起来很像是“针对接口编程,不针对实现编程”,的确很相似,然而这里更强调“抽象”。这里就是要求设计者们编程时需要有一定的抽象思维啦。

依赖倒置的原则,也可以让三层架构升级,具有抽象化。

e089661b739f9d30940037db9df1814e.png

▲图/ 升级抽象化三层架构示例

当然DIP的主要目的并不是这,目的就是为了让系统架构更加的稳定、更加灵活,更好的应对需求的变化。

无论多少种设计模式或者多少种设计原则,主要就是让系统稳定,能够应付需求的千变万化,并不是花里胡哨的存在。毕竟,相对于细节的多变性,抽象化会更加稳定。

那么程序中要使用依赖倒置原则,一个呼声最高的名词就是控制反转(Inversion of Control),简称IOC。

IOC的存在可以说是更好的实现依赖倒置原则,也让程序更加的灵活和稳固。

至于怎么理解这个IOC呢,可以请出女朋友的例子来说明。

女朋友饿了,想要吃这吃那,对食物有需求。

此时会怎么做呢?

1.自己去找吃的,去冰柜或者厨房去拿吃的。

2.找男朋友,向你撒娇,给她递食物。

第一种,女朋友可能不太聪明,也不会做饭,拿到的食品没有加工,或者没有清洗就直接吃,会存在一定的风险。

第二种,向男朋友撒娇,表达需求。此时你可能会表现出男友力Max,会去冰柜里拿出食物并洗干净给她,或者进厨房做饭给她吃,甚至还可以喂她。

啊?你要上班或者出差不在家?此时你女朋友发现隔壁邻居老王很富有且很会做饭,便向隔壁老王打电话撒娇表达需求,此时隔壁老王会做一手拿手好菜端到你女友面前并喂她。

我们可以看到,你的女朋友从对食物的需求,从主动去冰柜或者厨房(正转)获取食物,到想要吃食物而被动(你或者老王)获得(反转)食物。

女朋友对食物的需求,食物的控制权转移到了你或者老王的手上。

编程时,相当于组件对象控制权的转移。

例如,方法A中需要使用方法B,方法B需要使用方法C,此时方法B和方法C并不由自己本身来负责,而是由第三方来创建!

这个过程,称为控制反转,最直观的体现就是依赖注入(DI),反转依赖。

上述例子,女朋友想要的是食物(依赖,对食物的依赖),食物由第三方的你(男朋友)或者老王来负责,做好之后拿给(注入)你女朋友。

控制反转的是一种结果,一种由依赖食物到注入给定目标的结果。正是因为有了依赖注入,才需要控制反转,控制依赖的对象的选择权反转到目标结果。

如果明白了以上的内容,就能明白依赖注入和控制反转的目的。

为什么要依赖注入?因为要实现控制反转

为什么要控制反转?因为软件设计体系中需要符合依赖倒置原则

说到IOC(控制反转),我们会听到IOC容器的概念,IOC和IOC容器也有本质的区别。

IOC,定义就是一种反转流、依赖和接口的方式,它把传统上由程序代码直接操控的对象的调用权交给第三方(容器),通过第三方来实现对象组件的装配和管理。

所谓的IOC容器,可以理解为一个对象,通常是由依赖注入框架来提供的。负责映射依赖、管理对象的创建和生命周期。

说到IOC对象,我想大家应该有一个概念,就是对象池的概念。IOC容器可以理解为一个对象池的概念。

例如耳熟能详的数据库连接池,线程池等都是对象池的概念。

所谓的对象池,就是对象的容器,通过在一个容器中池化(实例化,也就是new)对象,并根据需要重复使用这些池化对象来满足性能上的需求。

当一个对象被激活时,便从池子里取出。用完时,又放回池中,等待下一个请求。一般用于对象的初始化过程代价较大或者使用频率较高的场景。

通俗讲,就是多个对象的实例化,资源释放都是交给对象池来处理。

fce2dafa958947ed3e080a2afc208139.png

依赖注入框架,目前使用较多的有 Unity、Autofac、Ninject等。

相关的框架也可以通过搜集文档进行了解,此处以Unity框架作为例子来实现。

7c537f565dce618ce5e9437f73752092.png

▲图/ 抽象化鸟类示例

//鸟类接口public interface IBird{public string Eat();}public class Cuckoo : IBird{public string Eat(){return "布谷鸟正在吃东西...";}}public class Sparrow : IBird{public string Eat(){return "麻雀鸟正在吃东西...";}}//鸟类工厂public static IBird GetEat(string birdType){if (string.IsNullOrEmpty(birdType)){return null;//这里可以使用空对象模式}switch (birdType){case "Cuckoo": return new Cuckoo();case "Sparrow": return new Sparrow();default:return null;}}//工厂方法调用 public class BirdSample{public IBird _bird { get; set; }public BirdSample(string birdType){_bird = BirdFactory.GetEat(birdType);}public void Eat(){Console.WriteLine($"小鸟们开始,吃东西了");Console.WriteLine(_bird.Eat());}}}
//普通调用方法,由工厂实例对象public static void Main(string[] args){BirdSample birdSample = new BirdSample("Cuckoo");birdSample.Eat();}
//使用Unity容器化public static void Main(string[] args){var container = new UnityContainer();//此处通过反射的方式实现,通过扫描程序集,找到相应的类进行主从到容器//注册类型可以更改,也可以通过配置文件,动态加载container.RegisterType<IBird, Cuckoo>();container.RegisterType<BirdSample>();var bird = container.Resolve<BirdSample>();bird.Eat();}

以上内容,就是依赖倒置原则,IOC的内容了。

希望能够帮助到伙伴们,文中示例有可能引发分手风险,在此希望多加支持点个赞!

👇 更多有趣内容,请多关注!👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/288004.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt 第二步 槽与信号(一) 实现点击按钮并弹窗

信号与槽是Qt中的核心&#xff0c;也是Qt的特有的。在Qt中信号与槽的关键字为slots、signals、emit。 具体信号与槽将会在下一节中详细说明&#xff0c;因为担心一些读者在没了解过槽与信号前直接讲述过深导致门槛提高&#xff0c;阅读困难&#xff0c;所以当前这一篇文将在不理…

语言 分组计算hr_干货 | HR不得不知的面试技巧

面试是求职者倍感煎熬的时刻&#xff0c;但其实&#xff0c;面试也让不少HR们颇有压力。毕竟&#xff0c;要在短时间内快速了解一个人&#xff0c;并判断是否适合岗位、业务部门会不会满意、能不能适应企业文化等并不容易。所以&#xff0c;今天Anna给大家整理了一份面试问题汇…

python3 爬虫第一步 简单获取网页基本信息

注&#xff1a;本系列专栏需要有简单的python3 语言基础 爬虫的相关作用在此就不再说明&#xff0c;相信能够点进该系列文章的读者都已经了解了爬虫是什么&#xff0c;并且能够做什么。由于是发布在互联网的文章&#xff0c;所以系列文章都不以书籍的方式从头到尾的叙述作用及其…

将旧版 WCF 应用程序迁移到 CoreWCF

前言CoreWCF 项目团队发布了 CoreWCF 的 1.0 版本&#xff0c;这是 WCF 到 .NET Core 平台的移植。我觉得&#xff0c;CoreWCF 适用于这类场景使用——基于 WCF 的旧版应用程序已在 Windows 平台上运行了很多年&#xff0c;但是希望将代码迁移到 .NET Core&#xff0c;以利用 L…

记录我的学习历程--二维数组解决平面图形题

打印出3 7 2 4 6 81 5 9代码如下转载于:https://blog.51cto.com/4139737/1684269

实现线段切割法_漫画:如何实现抢红包算法?

发出一个固定金额的红包&#xff0c;由若干个人来抢&#xff0c;需要满足哪些规则&#xff1f;1.所有人抢到金额之和等于红包金额&#xff0c;不能超过&#xff0c;也不能少于。2.每个人至少抢到一分钱。3.要保证所有人抢到金额的几率相等。小灰的思路是什么样呢&#xff1f;每…

python3 爬虫第二步Selenium 使用简单的方式抓取复杂的页面信息

Selenium 简介 该系列专栏上一篇爬虫文章点击这里。 网站复杂度增加&#xff0c;爬虫编写的方式也会随着增加。使用Selenium 可以通过简单的方式抓取复杂的网站页面&#xff0c;得到想要的信息。 Selenium 是操作浏览器进行自动化&#xff0c;例如自动化访问网站&#xff0c…

windows远程连接linux-安装xfce界面,ubuntn添加新用户

参考&#xff1a;“ 使用xrdp实现windows 远程桌面连接linux” http://blog.csdn.net/qq_33530388/article/details/64502902; http://www.linuxidc.com/Linux/2017-04/142690.htm 之前一直用mstsc连接windows主机&#xff0c;今天想用此来连接linux主机时&#xff0c;发现 连…

Qt 如何处理密集型耗时的事情

有时候需要处理一些跟界面无关的但非常耗时的事情&#xff0c;这些事情跟界面在同一个线程中&#xff0c;由于时间太长&#xff0c;导致界面无法响应&#xff0c;处于“假死”状态。例如&#xff1a;在应用程序中保存文件到硬盘上&#xff0c;从开始保存直到文件保存完毕&#…

【EPS精品教程】基于DOM和DSM创建垂直模型、加载垂直模型

本教程讲解EPS三维测图模块,主要内容有新建工程、创建垂直模型,为后续工作做准备。 目录 一、创建工程 二、生成垂直摄影模型

从旧金山到上海, HTTP/3 非常快!

HTTP/3 是超文本传输协议 (HTTP) 的第三个版本&#xff0c;它对 Web 性能来说意义重大, 让我们看看HTTP/3 如何让网站的速度变得更快&#xff01;等等&#xff0c;HTTP/2 发生了什么? 不是几年前才开始推广 HTTP/2 吗? 确实是这样, 但是它出现了一些 问题[1]&#xff0c; 包括…

最大尺寸分辨率_未来就在眼前——视涯科技推出最高分辨率硅基OLED显示屏幕...

声明&#xff1a;新闻稿非映维官方稿件&#xff0c;任何法律问题均与映维无关视涯科技•未来就在眼前2019年7月9日&#xff0c;在位于合肥新站高新区的自建工厂内&#xff0c;视涯科技(以下简称&#xff1a;“视涯”)作为一家半导体显示技术公司&#xff0c;公布开发中的两款硅…

Qt 第二步 熟悉文件结构组成(二)

目录导航&#xff1a; 《Qt 第一步 HelloWorld 的第一个程序》 《Qt 第二步 槽与信号&#xff08;一&#xff09; 实现点击按钮并弹窗》 本文参考《Qt5.9 c开发》 上一篇文使用了槽与信号完成了点击按钮并弹窗的程序效果&#xff0c;这一篇文将会了解Qt的项目文件组成。本节将会…

php基础教程 第一步 环境配置及helloworld

PHP 是服务器端脚本语言。全称为 Hypertext Preprocessor 为超文本预处理器。 据说php8不久后也要发布了&#xff0c;趁着8还没有发布赶紧写一个php5到php7&#xff08;在基础教程写完后将写php7新特性&#xff09;的教程。PHP版本之间更新会增加新特性&#xff08;别的语言也…

Hadoop(五)C#操作Hive

HiveHive将HiveQL&#xff08;类sql语言&#xff09;转为MapReduce&#xff0c;完成数据的查询与分析&#xff0c;减少了编写MapReduce的复杂度。它有以下优点&#xff1a;学习成本低&#xff1a;熟悉sql就能使用良好的数据分析&#xff1a;底层基于MapReduce实现同样存在一些缺…

深度优先搜索——八皇后问题

代码&#xff1a;&#xff08;控制台打印不了92种情况&#xff0c;只打印前10种&#xff09; 1 #include<iostream>2 #include<string>3 #include<windows.h>4 #define ok 15 #define error 06 using namespace std;7 8 9 int a[9][9]{0}; 10 int num0; 1…

python3 爬虫第三步 本文包你学会正则 不会就来锤我

简介 正则表达式是一种描述字符的一种方式&#xff0c;通过该方式&#xff0c;匹配字符串。 正则表达式是自由的&#xff0c;一个字符的含义往往代表着一类字符&#xff0c;通过多个正则正则符号的组合描述&#xff0c;可以使组成的正则表达式能够描述一类字符串。 在开发中&a…

.NET性能优化-使用结构体替代类

前言我们知道在C#和Java明显的一个区别就是C#可以自定义值类型&#xff0c;也就是今天的主角struct&#xff0c;我们有了更加方便的class为什么微软还加入了struct呢&#xff1f;这其实就是今天要谈到的一个优化性能的Tips使用结构体替代类。那么使用结构体替代类有什么好处呢&…

ISE14.7兼容性问题集锦

一、 关于win8和win10不兼容性解决办法 &#xff08;win7不会出现闪退的问题&#xff0c;按安装流程做完就可以直接使用了&#xff09; 在安装目录下&#xff0c;我这里是D:\ISE_14.7\14.7\ISE_DS\ISE\lib\nt64中找到libPortability.dll和libPortabilityNOSH.dll两个文件夹&…

幼儿园调查过程怎么写_深圳全托幼儿园哪个好 幼儿园寄宿怎么报名

陪孩子一起阅读的精髓不是认字和背诵&#xff0c;亲子阅读的那些事 亲子阅读是当代的养育新潮流&#xff0c;但它还有更可贵的一面。 脾气再大的妈妈&#xff0c;都有温柔可爱的时刻&#xff0c;就是陪伴孩子阅读的时刻&#xff0c;曾经有一位在我看来算不上温柔的妈妈&#xf…