美文网首页programming
依赖反转原则(Dependency Inversion Prin

依赖反转原则(Dependency Inversion Prin

作者: kkjusdoit | 来源:发表于2023-03-25 17:13 被阅读0次

规则:

  1. HIGH LEVEL MODULES SHOULD NOT DEPEND UPON LOW LEVEL MODULES. BOTH SHOULD DEPEND UPON ABSTRACTIONS.
  2. ABSTRACTIONS SHOULD NOT DEPEND UPON DETAILS. DETAILS SHOULD DEPEND UPON ABSTRACTIONS.

这里的层次是按照调用链划分,调用方是高层次,被调用的是低层次。

目的是尽可能是高低层级的模块松耦合,使其各自依赖抽象,而不是持有。

//  example without following the Dependency Inversion Principle

namespace SOLID_PRINCIPLES.DIP
{
    public class Employee
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Department { get; set; }
        public int Salary { get; set; }
    }

    public class EmployeeDataAccessLogic
    {
        public Employee GetEmployeeDetails(int id)
        {
            //In real time get the employee details from database
            //but here we have hard coded the employee details
            Employee emp = new Employee()
            {
                ID = id,
                Name = "Pranaya",
                Department = "IT",
                Salary = 10000
            };
            return emp;
        }
    }

    public class DataAccessFactory
    {
        public static EmployeeDataAccessLogic GetEmployeeDataAccessObj()
        {
            return new EmployeeDataAccessLogic();
        }
    }
    
    public class EmployeeBusinessLogic
    {
        EmployeeDataAccessLogic _EmployeeDataAccessLogic;
        public EmployeeBusinessLogic()
        {
            _EmployeeDataAccessLogic = DataAccessFactory.GetEmployeeDataAccessObj();
        }
        public Employee GetEmployeeDetails(int id)
        {
            return _EmployeeDataAccessLogic.GetEmployeeDetails(id);
        }
    }
}

对上述代码:
高层级模块EmployeeBusinessLogic依赖低层级模块EmployeeDataAccessLogic ,违反规则1:高级模块不应依赖于低级模块。两者都应该依赖于抽象

根据DIP,EmployeeBusinessLogic 不应该依赖EmployeeDataAccessLogic ,他们都应该依赖抽象类(或接口)

EmployeeBusinessLogic 和 EmployeeDataAccessLogic 都是具体的类,意味着我们可以创建他们的对象,这不符合规则2:抽象不应该依赖于细节,细节应该依赖抽象


using System;

namespace SOLID_PRICIPLES.DIP
{
    public interface IEmployDataAccessLogic
    {
        Employee GetEmployee(int id);
        //any other emplyee related method declarations

    }

    public class Employee
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Department { get; set; }
        public int Salary { get; set; }
    }
    public class EmployeeDataAccessLogic : IEmployDataAccessLogic
    {
        public Employee GetEmployee(int id)
        {
            Employee emp = new Employee()
            {
                ID = id,
                Name = "bob",
                Department = "IT",
                Salary = 10000
            };
            return emp;
        }
        public class DataAccessFactory
        {
            public static IEmployDataAccessLogic GetEmployeeDataAccessObj()
            {
                return new EmployeeDataAccessLogic();
            }
        }


        public class EmployeeBusinessLogic
        {
            IEmployDataAccessLogic _EmployeeDataAccessLogic;
            public EmployeeBusinessLogic()
            {
                _EmployeeDataAccessLogic = DataAccessFactory.GetEmployeeDataAccessObj();

            }

            public Employee GetEmployeeDetail(int id)
            {
                return _EmployeeDataAccessLogic.GetEmployee(id);
            }
        }






        public class Program
        {
            static void Main(string[] args)
            {
                EmployeeBusinessLogic employeeBusinessLogic = new EmployeeBusinessLogic();
                Employee employee = employeeBusinessLogic.GetEmployeeDetail(1001);
                Console.WriteLine($"ID: {employee.ID}, Name: {employee.Name}, Depart: {employee.Department}, salary:{employee.Salary}");
                Console.ReadKey();
            }
        }
    }
}

上面的例子使用 C# 语言实现了依赖倒置原则,其中高级模块 (EmployeeBusinessLogic) 和低级模块 (EmployeeDataAccessLogic) 依赖于抽象 (IEmployeeDataAccessLogic)。此外,抽象(IEmployeeDataAccessLogic)不依赖于细节(EmployeeDataAccessLogic),但细节依赖于抽象。

chat-gpt 解释

When following this principle, the conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are reversed, thus rendering high-level modules independent of the low-level module implementation details. 分析这个语法结构 词汇解释

这段话是一个相对较复杂的句子,其中有一些专业术语。以下是每个词汇的解释:
principle: 原则、准则、规则。
conventional: 传统的、惯例的、常规的。
dependency: 依赖、依存关系。在计算机科学中,指一个模块或组件需要另一个模块或组件来完成其工作的关系。
high-level: 高层次的、高级的。在计算机科学中,指较为抽象的模块或组件,通常是更高级别的管理或决策层。
policy-setting: 政策制定的、制定策略的。在计算机科学中,指负责制定策略或规则的模块或组件。
low-level: 低层次的、低级的。在计算机科学中,指更接近计算机硬件的模块或组件,通常是处理底层操作或实现特定功能的模块。
implementation: 实现、执行。在计算机科学中,指将设计转化为代码的过程。
detail: 细节、详情、具体情况。
因此,这段话可以理解为:遵循这个原则,高层次、制定策略的模块不再依赖于低层次、实现细节的模块,因为依赖关系被颠倒了,从而高层次模块不再受低层次模块实现细节的影响。

rendering 如何理解?
在这个句子中,"rendering" 指的是 "making" 或 "causing to be" 的意思。也就是说,这个原则使得高层次的模块与低层次的模块实现细节之间的依赖关系被颠倒,从而使高层次的模块不再依赖于低层次的模块,从而实现了高层次模块与低层次模块之间的解耦。因此,可以将 "rendering" 翻译为 "使得"、"使得成为"、"导致"等意思。

(英文中的, 有时候是汉语的顿号、 )

依赖倒置原则(Dependency Inversion Principle,DIP)的一个例子是,一个高层次的模块(比如一个业务逻辑层)应该依赖于一个抽象的接口或类,而不是依赖于一个具体的实现类。具体的实现类应该依赖于抽象接口或类,而不是反过来。

例如,假设我们有一个电子商务应用程序,其中有一个 "PaymentProcessor" 类用于处理支付。传统上,这个类可能会直接依赖于一个具体的支付服务(例如 "PaypalPaymentService"),并在其中调用支付服务的具体实现方法。这样,当我们想要更换支付服务时,需要修改 "PaymentProcessor" 类的代码,这违反了依赖倒置原则。

相反,如果我们使用依赖倒置原则,我们将创建一个抽象的支付服务接口(例如 "PaymentService"),并让 "PaypalPaymentService" 类实现这个接口。然后,"PaymentProcessor" 类将依赖于 "PaymentService" 接口,而不是直接依赖于 "PaypalPaymentService" 类。这样,当我们想要更换支付服务时,我们只需要创建另一个实现 "PaymentService" 接口的类即可,而不需要修改 "PaymentProcessor" 类的代码。

Unite Austin 2017 - S.O.L.I.D. Unity

before after DIP

相关文章

网友评论

    本文标题:依赖反转原则(Dependency Inversion Prin

    本文链接:https://www.haomeiwen.com/subject/qudnrdtx.html