ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

0x04、设计模式原则 —— 依赖倒置(倒转)原则

2022-04-01 23:01:22  阅读:228  来源: 互联网

标签:原则 0x04 void 接口 tv ITV new 设计模式 public


概念

先理解下面两个概念:

  • 抽象:接口或抽象类
  • 细节:具体的实现类

依赖倒置有如下5条概念:

  1. 高层模块不应该依赖低层模块,二者都应该依赖其抽象
  2. 抽象不应该依赖细节,细节应该依赖抽象
  3. 依赖倒转(倒置)的中心思想是面向接口编程
  4. 依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。
  5. 使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成

先了解什么意思,后必须记熟这5条概念,很重要的!! (我觉得这5条很白话文了,如果你还是不理解,建议做一个 Asp.Net Core Web Api 仓储模式 项目,这仓储模式里面用到的就是:面向接口编程的,里面用的这个模式太明显了)

不理解的,先看下面演示 !

 

演示

第一版,我们很传统的写法方式:

Persion _persion = new Persion();
_persion.receive(new Email());

class Email
{
    public string getInfo()
    {
        return $"电子邮件信息:hello,world.";
    }
}

// 完成 Persion 接收消息的功能
class Persion
{
    // 这里依赖了Email这个类(即:细节、实现)
    public void receive(Email email)
    {
        Console.WriteLine(email.getInfo());
    }
}

上面代码中,Persion类中强依赖了 Email 类(细节),如果下次我换成 接收WeChat类 呢?肯定是 需要在 Persion 类中增加相应的方法了吧;

我们思考下,依赖倒置原则是:面向接口编程,依赖的是抽象,而不是具体的实现,上面代码中,我们可以把依赖的细节(),改为依赖的是一个抽象;

即:新增一个抽象接口 IReceiver,表示接收者,这样Persion 类与接口发生了依赖;

因为 Email, WeiXin 等属于接收的范围,他们各自实现IReceiver接口就ok,这样我们就符合了依赖倒转原则;

Persion _persion = new Persion();
_persion.receive(new Email());
_persion.receive(new WeChat());


interface IReceiver
{
    public string getInfo();
}

class Email : IReceiver
{
    public string getInfo()
    {
        return $"电子邮件信息:hello,world.";
    }
}
class WeChat : IReceiver
{
    public string getInfo()
    {
        return $"微信信息:hello,kiki.";
    }
}
class Persion
{
    // 这里,我们是第接口的依赖了
    public void receive(IReceiver receiver)
    {
        Console.WriteLine(receiver.getInfo());
    }
}

 

依赖关系传递的三种方式和应用案例

接口传递

class Changhong : ITV
{
    public void play()
    {
        Console.WriteLine("打开长虹电视");
    }
}
public static void Main(string[] args)
{
    OpenAndClose openAndClose =new OpenAndClose();
    openAndClose.open(new Changhong());
}

// 方式1:通过接口传递实现依赖
// 开关的接口
interface IOpenAddClose
{
    public void open(ITV tv);   // 抽象方法、接收接口
}

interface ITV
{
    public void play();
}

class OpenAndClose : IOpenAddClose
{
    // 实现接口
    public void open(ITV tv)
    {
        tv.play();
    }
}

  

构造方法传递(超常见)

class Changhong : ITV
{
    public void play()
    {
        Console.WriteLine("打开长虹电视");
    }
}
public static void Main(string[] args)
{
    OpenAndClose openAndClose =new OpenAndClose(new Changhong());
    openAndClose.open();
}

// 方式1:通过接口传递实现依赖
// 开关的接口
interface IOpenAddClose
{
    public void open();   // 抽象方法、接收接口
}

interface ITV
{
    public void play();
}

class OpenAndClose : IOpenAddClose
{
    private readonly ITV _tv;

    public OpenAndClose(ITV tv)
    {
        _tv = tv;
    }
    // 实现接口
    public void open()
    {
        _tv.play();
    }
}

 

Setter传递(不常见)

class Changhong : ITV
{
    public void play()
    {
        Console.WriteLine("打开长虹电视");
    }
}
public static void Main(string[] args)
{
    OpenAndClose openAndClose =new OpenAndClose();
    openAndClose.setTv(new Changhong());
    openAndClose.open();
}

// 方式1:通过接口传递实现依赖
// 开关的接口
interface IOpenAddClose
{
    public void open();   // 抽象方法、接收接口

    public void setTv(ITV tv);
}

interface ITV
{
    public void play();
}

class OpenAndClose : IOpenAddClose
{
    private ITV _tv;

    public void setTv(ITV tv)
    {
        this._tv = tv;
    }
    // 实现接口
    public void open()
    {
        _tv.play();
    }
}

 

注意和细节

  1. 低层模块尽量都要有抽象类或接口,或者两者都有,程序稳定性更好;
  2. 变量的声明类型尽量是抽象类或接口, 这样我们的变量引用和实际对象间,就存在一个缓冲层,利于程序扩展和优化;(这句话不太好理解,看下面解释)
  3. 继承时遵循里氏替换原则 (这个下一节就说到了)

第2点 解释:假设,有 类A 继承 抽象接口B,那么存在:B b = new A();  b变量作为缓冲层,如果有 类C 继承至 抽象接口B,那么也可以: B b = new C(),即:

interface B{}
class A: B{}
class C: B{}
B b = new A();
b = new C();

// b变量就是一个缓冲层的意思,在 B 和 A 或者 B 和 C 之间

还是不懂的话,建议先放一放,做一些 面向接口编程 的项目后,在来这里回顾一下就行了;

 

这章其实有一点点难以理解,但是你迟早会看懂这个的,因为目前web的后端开发的的项目中,都用到了这个原则,比如 Asp.NET Core 的仓储模式 ;

好了,下一章,里氏替换原则 ,走起~

标签:原则,0x04,void,接口,tv,ITV,new,设计模式,public
来源: https://www.cnblogs.com/abc1069/p/16089268.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有