博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
依赖倒置原则
阅读量:5328 次
发布时间:2019-06-14

本文共 2997 字,大约阅读时间需要 9 分钟。

概述

上层模块不应该依赖于下层模块,二者都应该依赖于抽象。

抽象不应该有具体的实现,但是具体的实现应当依赖于抽象。

描述

在系统架构分析和设计中,软件的创建总是会带有一些错误的依赖关系,比如说业务逻辑依赖于底层实现,这种情形往往会导致业务逻辑变更,下层实现随之改变。当然,反过来也是成立的。因此,我们需要将彼此的依赖关系进行反转,这也是依赖倒置原则被引入的原因。

下面我们以按钮和灯的关系来进行讲解。

一般情况下,我们会这样的组织二者之间的关系:

using System;namespace DependencyInversionDaemon{    class Light    {        public void TurnOn()        {            Console.WriteLine("The light is on.");        }        public void TurnOff()        {            Console.WriteLine("The light is off.");        }    }}
Light.cs代码
namespace DependencyInversionDaemon{    class ButtonEx    {        private Light light = new Light();        private bool pressed = false;        public void Press()        {            if (pressed)                light.TurnOn();            else                light.TurnOff();            pressed = !pressed;        }    }}
ButtonEx.cs代码

Light类被ButtonEx类控制,这是典型的耦合度过高的设计。控制的逻辑部分在ButtonEx中,而下层的扩展则在Light类中,所以,ButtonEx类属于上层扩展部分而Light类则属于下层扩展部分。

所以,依赖方向是从ButtonEx类流向了Light类。如果Light类需要进行扩展,那么ButtonEx类将会受到影响。这就意味着,下层需求部分的改变将会影响上层应用部分。

重构

理想情况下,业务逻辑将会决定下层代码如何扩展,所以,下层模块应该依赖于业务逻辑。

但是,通过依赖倒置原则,我们应该讲ButtonEx类和Light类进行解耦,解耦的方式就是引入一个虚类,这个虚类能够将Light类中的具体行为抽象出来。

现在,我们在类中新加入一个Switchable类,这个类包含了ButtonEx类所需要的各种操作(也就是上层扩展中所需要的各种操作功能,比如TurnOn,TurnOff等)。ButtonEx类和Light类将不会直接的进行调用,而是通过这个Switchable中间类实现依赖倒置。

namespace DependencyInversionDaemons{    interface Switchable    {        void TurnOn();        void TurnOff();    }}
Switchable.cs代码
using System;namespace DependencyInversionDaemons{    class Light:Switchable    {        public void TurnOn()        {            Console.WriteLine("The light is on.");        }        public void TurnOff()        {            Console.WriteLine("The light is off.");        }    }}
Light.cs代码
using System;namespace DependencyInversionDaemons{    class Fridge:Switchable    {        public void TurnOn()        {            Console.WriteLine("The fridge is on.");        }        public void TurnOff()        {            Console.WriteLine("The fridge is off.");        }    }}
Fridge.cs代码
namespace DependencyInversionDaemons{    class ButtonEx    {        private Switchable swithableObjects;        private bool pressed = false;        public void SetSwitchable(Switchable switchable)        {            this.swithableObjects = switchable;        }        public void Press()        {            if (pressed)                swithableObjects.TurnOn();            else                swithableObjects.TurnOff();            pressed = !pressed;        }    }}
ButtonEx.cs代码
using System;namespace DependencyInversionDaemons{    class Program    {        static void Main(string[] args)        {            ButtonEx button = new ButtonEx();            button.SetSwitchable(new Fridge());            button.Press();            button.Press();            Console.ReadKey();         }    }}
调用代码

现在,当我们向这个工程里添加其他的设备的时候,就不需要改变ButtonEx类中的任何代码,这种依赖关系已经被解耦了。这种设计符合面向对象原则:松耦合,高内聚。

最后需要补充一点就是,依赖倒置原则,其实需要我们不要为实现而编程,要为接口编程。

转载于:https://www.cnblogs.com/scy251147/p/3268519.html

你可能感兴趣的文章
django优化--ORM优缺点
查看>>
黑马day16 jquery&属性过滤选择器
查看>>
PHP再学习5——RESTFul框架 远程控制LED
查看>>
FL2440-学习记录(三)
查看>>
Amobea读写分离
查看>>
关于密码
查看>>
oracle创建表空间
查看>>
Keycloak服务器安装和配置
查看>>
C#委托之个人理解(转)
查看>>
retrofit2 上传图片
查看>>
Linux Shell流程例子
查看>>
jQuery的三种$()
查看>>
2017.6.4 入门组 NO.4——猜数
查看>>
Eclipse 下载安装
查看>>
WebSocket 时时双向数据,前后端(聊天室)
查看>>
关于cocoa 运行时runtime
查看>>
关于python中带下划线的变量和函数 的意义
查看>>
asp.net 写入excel时,不能更新。数据库或对象为只读。
查看>>
题1简化版
查看>>
linux清空日志文件内容 (转)
查看>>