首页 > 其他分享 >设计原则 (5) 依赖倒置原则

设计原则 (5) 依赖倒置原则

时间:2024-02-29 16:58:38浏览次数:27  
标签:依赖 原则 依赖于 Printer User 模块 倒置 public

简介

依赖倒置原则(Dependency Inversion Principle,DIP)是面向对象设计中的一个重要原则,它强调了高层模块不应该依赖于低层模块,二者都应该依赖于抽象;而且抽象不应该依赖于具体实现细节,具体实现细节应该依赖于抽象。简而言之,高层模块和低层模块都应该依赖于抽象,而不是依赖于具体的实现。

主要思想:

  1. 高层模块与低层模块之间的解耦:高层模块和低层模块都应该依赖于抽象,而不是依赖于具体的实现细节,从而实现了高层模块与低层模块之间的解耦。

  2. 抽象不应该依赖于具体实现细节:抽象应该定义接口或者抽象类,不应该依赖于具体的实现细节。具体的实现细节应该依赖于抽象,而不是反过来。

案例

假设我们有一个电子设备管理系统,其中有一个User类负责使用打印机来打印文件。首先我们看一个不遵守依赖倒置原则的设计:

using System;

// 高层模块 User
public class User
{
    // 依赖于具体的低层模块 Printer
    private Printer printer = new Printer();

    public void PrintDocument(string document)
    {
        printer.Print(document);
    }
}

// 低层模块 Printer
public class Printer
{
    public void Print(string document)
    {
        Console.WriteLine("Printing: " + document);
    }
}

class Program
{
    static void Main(string[] args)
    {
        User user = new User();
        user.PrintDocument("Document 1");
    }
}

在这个设计中,User类直接依赖于具体的Printer类,导致高层模块和低层模块之间存在了紧耦合关系,违背了依赖倒置原则。如果需要更换打印机或者增加其他类型的设备,就需要修改User类的代码。

下面是遵守依赖倒置原则的设计:

using System;

// 抽象接口 IPrinter
public interface IPrinter
{
    void Print(string document);
}

// 低层模块 Printer 实现了 IPrinter 接口
public class Printer : IPrinter
{
    public void Print(string document)
    {
        Console.WriteLine("Printing: " + document);
    }
}

// 高层模块 User 依赖于抽象接口 IPrinter
public class User
{
    private IPrinter printer;

    // 通过构造函数注入打印机对象
    public User(IPrinter printer)
    {
        this.printer = printer;
    }

    public void PrintDocument(string document)
    {
        printer.Print(document);
    }
}

class Program
{
    static void Main(string[] args)
    {
        // 创建 Printer 对象并传递给 User 类
        IPrinter printer = new Printer();
        User user = new User(printer);
        user.PrintDocument("Document 1");
    }
}

在这个设计中,User类依赖于抽象接口IPrinter,而不是具体的Printer类。这样做使得User类不再依赖于具体的打印机实现,而是依赖于抽象的打印机接口,从而实现了高层模块和低层模块之间的解耦。如果需要更换打印机或者增加其他类型的设备,只需要修改依赖注入的部分,而不需要修改User类的代码,符合了依赖倒置原则。

优点

  1. 降低耦合性:依赖倒置原则能够降低系统各个模块之间的耦合度,使得高层模块和低层模块之间的依赖关系更加松散,从而提高了系统的灵活性和可维护性。

  2. 增强可扩展性:由于高层模块不依赖于具体的低层模块,而是依赖于抽象,因此系统更容易进行功能的扩展和修改,增强了系统的可扩展性和可维护性。

  3. 提高代码的可读性和可维护性:依赖倒置原则使得代码的依赖关系更加清晰、简单,易于理解和维护,提高了代码的可读性和可维护性。

  4. 提高代码的重用性:由于系统各个模块之间的依赖关系更加松散,因此模块的重用性也会增加,提高了代码的重用性和可复用性。

缺点

  1. 增加设计和开发成本:遵循依赖倒置原则需要对系统进行合理的设计和抽象,可能会增加一些额外的设计和开发成本。

  2. 增加学习成本:依赖倒置原则需要对面向对象设计原则有一定的了解,对开发人员的学习成本有一定的挑战。

  3. 可能导致过度设计:为了遵循依赖倒置原则,可能会过度设计接口和抽象类,将一个功能细分为多个模块,这可能会增加系统的复杂度,降低系统的可理解性和可维护性。

标签:依赖,原则,依赖于,Printer,User,模块,倒置,public
From: https://www.cnblogs.com/mchao/p/18044737

相关文章

  • 设计原则 (3) 里氏替换原则
    简介里氏替换原则(LiskovSubstitutionPrinciple,LSP)是面向对象设计中的一个重要原则,由芭芭拉·利斯科夫(BarbaraLiskov)在1987年提出。它是继承原则的一种深化和发展,强调子类必须能够替换掉父类并且不影响程序的正确性。里氏替换原则的定义为:“如果对每一个类型为S的对象o1,都......
  • 关于pom.xml各种起步依赖
     <?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/P......
  • FastAPI系列:依赖注入
    函数式依赖项fromfastapiimportFastAPIfromfastapiimportQuery,Dependsfromfastapi.exceptionsimportHTTPExceptionapp=FastAPI()defusername_check(username:str=Query(...)):ifusername!='zhong':raiseHTTPException(status_code......
  • 迪米特原则(设计默斯和)
    定义 高内聚低耦合是一个非常重要的设计思想,能够很好的提高代码的可读性和可维护性,缩小功能改动导致导致代码改动范围,实际上,在前面的章节中,我们已经多次提到了这个设计思想。很多设计原则都是以代码的高内聚低耦合为目的的,比如单一原则,基于接口而非编程实现实际上,高内部松耦合,......
  • 【Spring Framework】IoC容器、依赖注入 + 基于XML && 基于注解 && 基于Java Config配
    概念IoC,InversionofControl,控制反转:将对象的控制权交由第三方统一管理DI,DependencyInjection:依赖注入,使用反射技术,是一种IoC的实现SpringIoC容器:用于统一创建与管理对象依赖XML管理对象(bean):applicationContext.xmlSpring框架使用流程-基于XML配置IoC容器1.导入spring......
  • KISS 原则 (设计模式)
    KISS定义kiss原则的英文描述又几个版本,计较下边的这几个keepitsimpleandstupid.keepitshortandsimplekeepitsimpleandstraightforward不过仔细看你会发现,他们表达的意思其实差不多,尽量保持简单。它是一个万金油的设计原则,可以在很多场景中,它不仅仅经常用来指......
  • 解析Spring中的循环依赖问题:再探三级缓存(AOP)
    前言在之前的内容中,我们简要探讨了循环依赖,并指出仅通过引入二级缓存即可解决此问题。然而,你可能会好奇为何在Spring框架中还需要引入三级缓存singletonFactories。在前述总结中,我已经提供了答案,即AOP代理对象。接下来,我们将深入探讨这一话题。AOP在Spring框架中,AOP的实现是通......
  • Spring系列之(四)Spring的依赖注入
    Spring的依赖注入在当前类需要用到其他类的对象,其他类的对象也是由Spring创建并将引用传递给当前类的对象的,我们只需要在配置文件中说明,说白了就是为当前类填充(也叫注入)其他类的对象1.能够注入的数据能够注入的数据是指支持注入的这部分数据是可以被Spring填充(注入)到当前类的......
  • springboot2.6开始禁止循环依赖了
    参考文章: https://mp.weixin.qq.com/s?__biz=MzI0MTUwOTgyOQ==&mid=2247497189&idx=1&sn=0f03cdafad9bacef66c64a490b85ff23&scene=21#wechat_redirect使用了SpringBoot2.6及以上版本的,如果要允许循环依赖,可以作如下设置:方案二:允许循环引用此方案更像是绕过问题而非解决问题......
  • 接口隔离原则(设计模式)
    定义“Clientsshouldnotbeforcedtodependuponinterfacesthattheydonotuse”个人认为接口隔离原则,和单一原则有点像。一个接口实现一个功能。 不过,你应该已经发现,接口隔离原则跟单一职责原则有点类似,不过稍微还是有点区别。单一职责原则针对的是模块、类、接口......