• 谈谈我对DI的理解


    本文中DI指依赖倒置

    依赖的概念

    Baidu百科:依靠别人或事物而不能自立或自给。

    软件开发中的依赖:依赖描述了两个模型元素之间的关系,如果被依赖的模型元素发生变化就会影响到另一个模型元素。

    DI的概念

    A. 上层模块不应该依赖于下层模块,它们共同依赖于一个抽象。
    B. 抽象不能依赖于具象,具象依赖于抽象。

    实例谈开

    在分层开发中,通常会有这样的两个模块:DAL(数据访问层)和BLL(业务逻辑层) 。 下面就以电子商务系统中的 订单、产品、用户 为例来说说这两个模块之间的依赖关系。

    正向依赖

    DAL:

    public class OrderDao 
    {
        
    public List<Orders> GetOrderByUserID(int userid)
        {
            
    throw new NotImplementedException();
        }
        
    public List<Orders> GetOrderByProductID(int productID)
        {
            
    throw new NotImplementedException();
        }
    }

    BLL:

    public class Order
    {
        
    private OrderDao orderDao;//对DAL中OrderDao的引用
        public Order(OrderDao orderDao)
        {
            orderDao 
    = orderDao;
        }
        
    public List<Orders> GetOrderByUserID(int userid)
        {
            List
    <Orders> list = null;
            list 
    = orderDao.GetOrderByUserID(userid);
            
    return list;
        }
        
    public List<Orders> GetOrderByProductID(int productID)
        {
            List
    <Orders> list = null;
            list 
    = orderDao.GetOrderByProductID(productID);
            
    return list;
        }
    }

     BLL中Order持有了DAL中OrderDao的引用,这个时候BLL模块依赖于DAL模块。他们之间构成了紧耦合。如果要更换DAL模块,显然需要修改BLL中的代码。

    引入抽象

    依赖倒置的思想告诉我们上层模块(BLL)和下层模块(DAL)都应当依赖于抽象。那么我们引入一个抽象模块。

    抽象模块:

    public interface IOrderDao
    {
        List
    <Orders> GetOrderByUserID(int userid);

        List
    <Orders> GetOrderByProductID(int productID);
    }

    DAL:

    public class OrderDao : IOrderDao//继承于抽象
    {
        
    public List<Orders> GetOrderByUserID(int userid)
        {
            
    throw new NotImplementedException();
        }
        
    public List<Orders> GetOrderByProductID(int productID)
        {
            
    throw new NotImplementedException();
        }
    }

    BLL:

    public class Order
    {
        
    private IOrderDao orderDao;//依赖于抽象
        public Order(IOrderDao orderdao)
        {
            orderDao 
    = orderdao;
        }
        
    public List<Orders> GetOrderByUserID(int userid)
        {
            List
    <Orders> list = null;
            list 
    = orderDao.GetOrderByUserID(userid);
            
    return list;
        }
        
    public List<Orders> GetOrderByProductID(int productID)
        {
            List
    <Orders> list = null;
            list 
    = orderDao.GetOrderByProductID(productID);
            
    return list;
        }
    }

    现在BLL持有了对抽象模块的引用,而DAL也依赖于该抽象模块。抽象模块的引入消除了BLL和DAL之间的依赖。那么这种方法是否完美呢?

    接口的单一性

    在一个业务驱动的系统中,如果与订单相关的业务发生变化,会导致我们去修改 IOrderDao,相应的DAL中的OrderDao 和BLL的Order都会被修改。

    什么原因呢?
    上面的这种设计让我们无法保持一个稳定的接口。面向对象设计中,有这样的两个原则:
    单一职责原则(SRP):保证对象的细粒度和单一性。

    开放-封闭原则(OCP):对于扩展开放,对于更改封闭。

    于是有了下面的设计。

    抽象模块:

    public interface IOrderUserDao
    {
        List
    <Orders> GetOrderByUserID(int userid);
    }
    public interface IOrderProductDao
    {
        List
    <Orders> GetOrderByProductID(int productID);
    }

    DAL:

    public partial class OrderDao : IOrderUserDao
    {
        
    public List<Orders> GetOrderByUserID(int userid)
        {
            
    throw new NotImplementedException();
        }
    }
    public partial class OrderDao : IOrderProductDao
    {
        
    public List<Orders> GetOrderByProductID(int productID)
        {
            
    throw new NotImplementedException();
        }
    }

    BLL:

    public class User
    {
        
    private IOrderUserDao orderDao;//依赖于抽象
        public User(IOrderUserDao orderdao)
        {
            orderDao 
    = orderdao;
        }
        
    public List<Orders> GetOrderByUserID(int userid)
        {
            List
    <Orders> list = null;
            list 
    = orderDao.GetOrderByUserID(userid);
            
    return list;
        }
    }

    public class Product
    {
        
    private IOrderProductDao orderDao;//依赖于抽象
        public Product(IOrderProductDao orderdao)
        {
            orderDao 
    = orderdao;
        }
        
    public List<Orders> GetOrderByProductID(int productID)
        {
            List
    <Orders> list = null;
            list 
    = orderDao.GetOrderByProductID(productID);
            
    return list;
        }
    }

    那么您的意见呢?




     

  • 相关阅读:
    php图片水印添加,压缩,剪切的封装类
    使用观察者模式处理异常信息
    php中的错误级别
    php 递归函数的三种实现方式
    php利用递归函数实现无限级分类
    利用http协议发布博客园博文评论
    结合php ob函数理解缓冲机制
    php 正则表达式捕获组与非捕获组
    php 利用socket发送GET,POST请求
    php mysqli扩展之预处理
  • 原文地址:https://www.cnblogs.com/tenghoo/p/DI.html
Copyright © 2020-2023  润新知