zoukankan      html  css  js  c++  java
  • 深入理解DIP、IoC、DI以及IoC容器

    1、依赖倒置原则(DIP):一种软件架构设计的原则(抽象概念)。   依赖倒置原则,它转换了依赖,高层模块不依赖于低层模块的实现,而低层模块依赖于高层模块定义的接口

    2、控制反转(IoC):一种反转流、依赖和接口的方式(DIP的具体实现方式)。

    控制反转(IoC),它为相互依赖的组件提供抽象,将依赖(低层模块)对象的获得交给第三方(系统)来控制即依赖对象不在被依赖模块的类中直接通过new来获取。在图1的例子我们可以看到,ATM它自身并没有插入具体的银行卡(工行卡、农行卡等等),而是将插卡工作交给人来控制,即我们来决定将插入什么样的银行卡来取钱。

    软件设计原则:原则为我们提供指南,它告诉我们什么是对的,什么是错的。它不会告诉我们如何解决问题。它仅仅给出一些准则,以便我们可以设计好的软件,避免不良的设计。一些常见的原则,比如DRY、OCP、DIP等。

    软件设计模式:模式是在软件开发过程中总结得出的一些可重用的解决方案,它能解决一些实际的问题。一些常见的模式,比如工厂模式、单例模式等等。

    3、依赖注入(DI):IoC的一种实现方式,用来反转依赖(IoC的具体实现方式)。

    控制反转(IoC)一种重要的方式,就是将依赖对象的创建和绑定转移到被依赖对象类的外部来实现

    依赖注入(DI),它提供一种机制,将需要依赖(低层模块)对象的引用传递给被依赖(高层模块)对象。通过DI,我们可以在Order类(订单类)的外部将SqlServerDal对象(数据库访问类)的引用传递给Order类对象。根据DIP原则,我们知道高层模块不应该依赖于低层模块,两者应该依赖于抽象。那么构造函数的参数应该是一个抽象类型。

    方法一:

    1. 首选,我们需要定义SqlServerDal的抽象类型IDataAccess,并在IDataAccess接口中声明一个Add方法。
      public interface IDataAccess
      {
              void Add();
      }
    2. 然后在SqlServerDal类中,实现IDataAccess接口。
      public class SqlServerDal:IDataAccess
      {
             public void Add()
             {
                 Console.WriteLine("在数据库中添加一条订单!");
             }
      }
    3.  接下来,我们还需要修改Order类。
      public class Order
      {
            private IDataAccess _ida;//定义一个私有变量保存抽象
            
              //属性,接受依赖   (也可以构造函数注入)
              public IDataAccess Ida
             {
                 set { _ida = value; }
                 get { return _ida; }
             }
       
             public void Add()
             {
                 _ida.Add();
             }
      }
       
    4. OK,我们再来编写一个控制台程序。
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
       
      namespace DIPTest
      {
          class Program
          {
              static void Main(string[] args)
              {
                  SqlServerDal dal = new SqlServerDal();//在外部创建依赖对象
                  Order order = new Order();//通过构造函数注入依赖
                  order.Ida = dal;    //给属性赋值
                  order.Add();
       
                  Console.Read();
              }
          }
      }
    5. 从上面我们可以看出,我们将依赖对象SqlServerDal对象的创建和绑定转移到Order类外部来实现,这样就解除了SqlServerDal和Order类的耦合关系。当我们数据库换成Access数据库时,只需定义一个AccessDal类,然后外部重新绑定依赖,不需要修改Order类内部代码,则可实现Access数据库的操作。
    6. 定义AccessDal类:
      public class AccessDal:IDataAccess
      {
              public void Add()
              {
                  Console.WriteLine("在ACCESS数据库中添加一条记录!");
              }
      }
    7. 然后在控制台程序中重新绑定依赖关系:
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
       
      namespace DIPTest
      {
          class Program
          {
              static void Main(string[] args)
              {
                   AccessDal dal = new AccessDal();//在外部创建依赖对象
                     Order order = new Order(dal);//通过构造函数注入依赖
       
                     order.Add();
       
                  Console.Read();
              }
          }
      }

    方法二:相比构造函数注入和属性注入,接口注入显得有些复杂,使用也不常见。具体思路是先定义一个接口,包含一个设置依赖的方法。然后依赖类,继承并实现这个接口。

    1. 首先定义一个接口IDAO: 
      public interface IDependent
      {
                 void SetDependence(IDataAccess ida);//设置依赖项
      }
    2. 依赖类实现这个接口:
      public class Order : IDependent
       {
           private IDataAccess _ida;//定义一个私有变量保存抽象
       
           //实现接口(通过构造函数注入)
           public void SetDependence(IDataAccess ida)
           {
               _ida = ida;
           }
       
           public void Add()
           {
               _ida.Add();
           }
       
       }
    3. 控制台程序通过SetDependence方法传递依赖:
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
       
      namespace DIPTest
      {
          class Program
          {
              static void Main(string[] args)
              {
                  AccessDal dal = new AccessDal();//在外部创建依赖对象
                Order order = new Order();
       
                  order.SetDependence(dal);//传递依赖
       
                  order.Add();
       
                  Console.Read();
              }
          }
      }

    IoC容器:依赖注入的框架,用来映射依赖,管理对象创建和生存周期(DI框架)。

    具体内容参考:http://www.cnblogs.com/liuhaorain/p/3747470.html

  • 相关阅读:
    Away3d学习笔记2三维世界的四个基本构件
    实验报告2
    实验报告
    WPF基础——Application
    COM技术内幕(笔记)
    关于一个GetLevelDesc函数 的认知问题
    UI库阶段性进展(完成文字列表,样式列表(样式列表可继承))
    UI库阶段性进展
    UI库阶段性进展(按钮初具雏形)
    UI库阶段性进展(button在文本对齐的基础上增加文本偏移让文本位置更精准)
  • 原文地址:https://www.cnblogs.com/step-city/p/5818741.html
Copyright © 2011-2022 走看看