zoukankan      html  css  js  c++  java
  • 企业级应用架构(一) 三层架构之解耦

     

     

    三层架构

    背景:

        项目的引用关系是:StructWed->BLL,Model;BLL->DAL,Model;DAL->Model。下面我们来演示一下程序流程,假设我们的数据库有一张订单表Order表,我们的业务是针对Order表进行的增删改查,那么根据三层架构的编程模式,我们就需要建立起对应的Model层实体,数据访问层实体和业务层实体,我们分别用OrderModel,OrderDAL,OrderBLL表示,代码如下,由于仅仅是为了演示,所以我并未提供相应的实现。

    Model:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Mode
    {
        public class OrderModel
        {
            public int ID { get; set; }
    
            public int productName { get; set; }
    
            public DateTime CreateTime { get; set; }
        }
    }
    View Code

    DAL:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Mode;
    
    namespace DaL
    {
        public class OrderDAL
        {
            /// <summary>
            /// 向Order表插入数据
            /// </summary>
            /// <returns>成功:true,失败:false</returns>
            public bool Insert()
            {
                return true;
            }
            /// <summary>
            /// 修改Order表数据
            /// </summary>
            /// <param name="model">表数据对应实体</param>
            /// <returns>成功:true,失败:false</returns>
            public bool Update(OrderModel model)
            {
                return true;
            }
            /// <summary>
            /// 删除Order表指定ID的记录
            /// </summary>
            /// <param name="id">表ID</param>
            /// <returns>成功:true,失败:false</returns>
            public bool Delete(int id)
            {
                return true;
            }
        }
    }
    View Code

    BLL:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using DaL;
    using Mode;
    
    namespace Bll
    {
        public class OrderBLL
        {
            protected OrderDAL orderDal = new OrderDAL();
            
            public bool Insert(OrderModel model)
            {
                //业务点1
                //业务点2
                return orderDal.Insert();
            }
    
            /// <summary>
            /// 修改Order表数据
            /// </summary>
            /// <param name="model">表数据对应实体</param>
            /// <returns>成功:true,失败:false</returns>
            public bool Update(OrderModel model)
            {
                //业务点1
                //业务点2
                 return orderDal.Update(model);
            }
            /// <summary>
            /// 删除Order表指定ID的记录
            /// </summary>
            /// <param name="id">表ID</param>
            /// <returns>成功:true,失败:false</returns>
            public bool Delete(int id)
            {
                //业务点1
                //业务点2
                return orderDal.Delete(id);
            }
        }
    }
    View Code

        好了,现在让我们把目光聚焦到OrderBLL上面来。我们发现OrderBLL对数据库Order表的所有操作都是在调用其内部创建的orderDAL实体的同名方法,换句话来说OrderBLL指示其内部orderDAL实体去完成数据库的增删改查。

        好现在,我们思考一下。假设有一天我们发现我们数据访问层的orderDAL实体代码写的很不优雅,效率极差,我们想用一个更优雅的实体,比如OrderActiveDAL去替换掉它,那么这个时候我们OrderBLL的代码就必须做相应的改动,如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using DaL;
    using Mode;
    
    namespace Bll
    {
        public class OrderBLL
        {
            protected OrderActive orderActive = new OrderActive();
            
            public bool Insert(OrderModel model)
            {
                //业务点1
                //业务点2
                return orderActive.Insert();
            }
    
            /// <summary>
            /// 修改Order表数据
            /// </summary>
            /// <param name="model">表数据对应实体</param>
            /// <returns>成功:true,失败:false</returns>
            public bool Update(OrderModel model)
            {
                //业务点1
                //业务点2
                 return orderActive.Update(model);
            }
            /// <summary>
            /// 删除Order表指定ID的记录
            /// </summary>
            /// <param name="id">表ID</param>
            /// <returns>成功:true,失败:false</returns>
            public bool Delete(int id)
            {
                //业务点1
                //业务点2
                return orderActive.Delete(id);
            }
        }
    }
    View Code

       这显然不是一种好的处理方式。我们追求的是在替换orderDal实体的同时,不修改OrderBLL的任何代码,换句话说就是解除BLL层与DAL层的耦合,为了达到这个目的,我们添加一个叫IDAL的接口类库,如图

        特别注意,我们在BLL层中添加了对IDA的引用,同时移除了对DAL的引用,这就意味着我们在BLL中无法创建(new)DAL层中的任何实体。下面我们在IDA项目中定义IOrder接口,如下

    using Mode;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace IDal
    {
        public interface IOrder
        {
            /// <summary>
            /// 向Order表插入数据
            /// </summary>
            /// <returns>成功:true,失败:false</returns>
            bool Insert();
           
            /// <summary>
            /// 修改Order表数据
            /// </summary>
            /// <param name="model">表数据对应实体</param>
            /// <returns>成功:true,失败:false</returns>
            bool Update(OrderModel model);
           
            /// <summary>
            /// 删除Order表指定ID的记录
            /// </summary>
            /// <param name="id">表ID</param>
            /// <returns>成功:true,失败:false</returns>
            bool Delete(int id);
        }
    }
    View Code

    我们让DAL引用IDAL,同时让OrderActiveDAL,OrderDal分别实现IOrder接口,如下

    using IDal;
    using Mode;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace DaL
    {
        class OrderActiveDAL : IOrder
        {
            /// <summary>
            /// 向Order表插入数据
            /// </summary>
            /// <returns>成功:true,失败:false</returns>
            public bool Insert()
            {
                return true;
            }
            /// <summary>
            /// 修改Order表数据
            /// </summary>
            /// <param name="model">表数据对应实体</param>
            /// <returns>成功:true,失败:false</returns>
            public bool Update(OrderModel model)
            {
                return true;
            }
            /// <summary>
            /// 删除Order表指定ID的记录
            /// </summary>
            /// <param name="id">表ID</param>
            /// <returns>成功:true,失败:false</returns>
            public bool Delete(int id)
            {
                return true;
            }
        }
    }
    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Mode;
    using IDal;
    
    namespace DaL
    {
        public class OrderDAL : IOrder
        {
            /// <summary>
            /// 向Order表插入数据
            /// </summary>
            /// <returns>成功:true,失败:false</returns>
            public bool Insert()
            {
                return true;
            }
            /// <summary>
            /// 修改Order表数据
            /// </summary>
            /// <param name="model">表数据对应实体</param>
            /// <returns>成功:true,失败:false</returns>
            public bool Update(OrderModel model)
            {
                return true;
            }
            /// <summary>
            /// 删除Order表指定ID的记录
            /// </summary>
            /// <param name="id">表ID</param>
            /// <returns>成功:true,失败:false</returns>
            public bool Delete(int id)
            {
                return true;
            }
        }
    }
    View Code

    现在我们队BLL层OrderBLL做相应的改动,把数据访问实体orderDAL的类型,定义为接口IOrder类型,如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using DaL;
    using Mode;
    using IDal;
    
    namespace Bll
    {
        public class OrderBLL
        {
            protected IOrder orderDal;
    
            public OrderBLL()
            { 
                //在这里需要实力化orderDal
            }
    
            public bool Insert(OrderModel model)
            {
                //业务点1
                //业务点2
                return orderDal.Insert();
            }
    
            /// <summary>
            /// 修改Order表数据
            /// </summary>
            /// <param name="model">表数据对应实体</param>
            /// <returns>成功:true,失败:false</returns>
            public bool Update(OrderModel model)
            {
                //业务点1
                //业务点2
                 return orderDal.Update(model);
            }
            /// <summary>
            /// 删除Order表指定ID的记录
            /// </summary>
            /// <param name="id">表ID</param>
            /// <returns>成功:true,失败:false</returns>
            public bool Delete(int id)
            {
                //业务点1
                //业务点2
                return orderDal.Delete(id);
            }
        }
    }
    View Code

        好了,现在让我们把目光聚集OrderBLL的构造函数。我们知道,OrderBLL会调用orderDAL去操作数据库,而orderDAL的类型为IOrder,也就是说但凡实现了IOrder接口的类实例都可以赋值给orderDAL。但是现在问题的关键是我们如何为orderDAL赋值,前面我们说过BLL移除了DAL的引用,所以在BLL层中直接去new数据访问层的实例,是不可能的。这里我提供两种处理方式,第一种采用IOC容器如spring.net帮助我们创建DAL层实例然后在OrderBLL的构造函数中赋值给orderDAL,另一种则是利用工厂模式和反射来创建DAL层实例了,本文将详述第二种,至于第一种在后面的系列中会有专门的章节讲述。现在我们在项目中添加一个Factoy工厂类库,并让

    BLL层引用Factoy类库,如图:

     

    接着我们来写工厂类。我们从配置文件中读出程序集路径和类的全名,利用反射的原理创建DAL层的实例,代码如下

    using IDal;
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Factory
    {
        public class OrderDALFactory
        {
    
            private static readonly string AssemblyName = ConfigurationManager.AppSettings["Assembly"];
            private static readonly string className = ConfigurationManager.AppSettings["className"];
            public static IOrder CreateOrder()
            {
                return (IOrder)Assembly.Load(AssemblyName).CreateInstance(className);
            }
        }
    }
    View Code

    最后我们在OrderBLL的构造函数利用OrderDALFactory工厂给orderDAL赋值

    public OrderBLL()
      { 
           //在这里需要实力化orderDal
           orderDal=OrderDALFactory.CreateOrder();
      }

    这样我们就实现了BLL与DAL层的解耦,当我们BLL需要不同的IOrder实体的时候,我们只需要修改相应的配置文件即可。

    原文链接:https://www.cnblogs.com/shaoshun/p/3804474.html

  • 相关阅读:
    Sqlserver 获得范围内的随机数过程
    Alpha项目测试
    第三次作业
    第二次作业
    Surprise团队项目总结
    Surprise团队第四周项目总结
    Surprise团队第三周项目总结
    Surprise团队第二周项目总结
    Surprise团队第一周项目总结
    5种常用的相关分析方法
  • 原文地址:https://www.cnblogs.com/youguess/p/10188550.html
Copyright © 2011-2022 走看看