精华内容
下载资源
问答
  • 在我们刚开始学习架构的时候,首先会想到分层的概念,分层架构比较经典的是架构,那么,什么是架构呢?它包括表现层、业务层、数据访问层;而对于一个新手来说,从抽象意义上的架构,逻辑上就划分为个层...

    在我们刚开始学习架构的时候,首先会想到分层的概念,分层架构比较经典的是三层架构,那么,什么是三层架构呢?它包括表现层、业务层、数据访问层;而对于一个新手来说,从抽象意义上的三层架构,逻辑上就划分为三个层。

    69e487379f9cdde040003791d257bb43.png

    这个是最基本的三层架构模式。

    表现层充当系统的界面呈现以及UI逻辑的角色,也就是说,UI(用户界面)属于表现层;

    举一个对于http://asp.net WebForm来说,人们喜欢把对于UI的控制逻辑(服务器控件的读取、设置、事件等等)写在页面的后置隐藏代码中,并且依赖业务逻辑层。当然,服务器控件支持数据绑定的功能,可以通过数据源进行绑定控件。这样就可以节省在后置隐藏中的代码。

    因此,我们就可以把表现层分为UI用户界面以及UI逻辑:

    d4981e4aec0db0e401556ab54c6952a3.png

    UI用户界面的职责只是作为数据输入和输出后的展示工作。

    UI逻辑的职责是负责业务逻辑层以及UI用户界面之间的数据交互,并且尽可能地让UI逻辑不依赖于UI技术。

    其中UI用户界面的实现方式有很多,包括http://ASP.NET、WinForm、WPF、Silverlight、移动Web、智能设备等等。

    29def9d9d70dee83d7a90e671b4176c4.png

    将表现层中UI页面和UI逻辑分离的策略中,当前使用最多的两种模式是MVC模式和MVP模式。

    MVC模式,即模型-视图-控制器模式,通过视图触发并执行某个操作,调用控制器,通过控制器去操作业务层,最终返回模型,在视图中进行展示。这里的模型可以是一个领域模型(DM),也可以是一个数据迁移对象(DTO)。

    MVP模式,即模型-视图-展示器模式,和MVC模式有点像,不同的是MVP中视图和模型是被完全分离出来的,视图中定义一个接口,而展示器通过调用该接口的方法以控制视图。因此,视图和模型是松散的,展示器也充当了一个控制器的角色,同时它也不依赖于UI技术。

    另外再介绍一种模式PM(Preentation Model),它可以说是MVP的变体,在PM中,视图不定义接口,这里的模型只是表示视图状态的类,视图中的元素被直接绑定到模型属性上。例如在WPF中,WPF就先天的具有数据双向绑定机制以及事件通知属性机制。

    所以它特别适用于WPF,Sliverlight等等。

    bd2a47f8c8d32f896ea244a9299cacdf.png

    在开始业务层之前,不得不说一个前提,在一个小型项目中,直接让表现层调用业务层,足以解决所有问题。但是,当项目大到使用多种表现形式,如使用了各种UI技术、http://ASP.NET、WPF、移动设备等等,就要考虑在你的表现层和业务层之间增加一个层,以至于让表现层和业务层解耦,因为业务层作为一个业务中间件的平台,最好不要暴露于表现层中,这个层就是传说中的服务层。架构图又演化为:

    85491629a81a5ee49e84678397711f90.png

    服务层实际上并不执行任何具体的工作,其功能在于组织各个业务对象,服务层将业务层所有的细节对表现层都隐藏起来,服务器将组织业务逻辑层中的组件,并且通过数据迁移对象(DTO)与表现层交互,因此就产生一个DTO模型。

    为了实现服务的可重用性,需要使用服务接口,表现层通过规定的接口访问功能。服务的实现继承服务接口,而服务的实现专注于业务层的调用。

    34461a1cea74f352a2f888a1b823e01c.png

    对于服务层,常用的方法包括Web服务、.NET Remoting、Rest以及WCF技术。

    本人比较建议使用WCF作为服务,因为可以方便地通过配置达到远程调用服务的目的。

    服务层消除了两个表现层和业务层之间的耦合,服务层可以实现一个远程接口,达到多UI技术甚至多平台上的通信。

    当然增加服务层也有缺点,假如使用WCF服务,会增加系统的调用开销,进而影响性能。

    ef4a4395bee51b6dc7ecfe36c172ba38.png

    业务层中包含系统所需要业务过程上的实现,并与下层的数据访问层交互。

    我们通常也叫做业务层叫做业务逻辑层,但我认为业务逻辑层是属于业务层的一方面,业务逻辑更专注于业务上逻辑算法的实现。因为业务层还可以包括其他的方面。

    业务层必须包括对业务实体尽心建模的对象模型,表达了客户的所有策略和需求的业务规则,因此就产生了领域模型。

    (PS:如果这里你不使用领域模型,那么需要采用业务规则层进行业务功能上的业务规则的验证和控制)

    领域模型包括对实体的属性定义,方法定义以及实体与实体之间的关系。从这个角度上看,UML建模至关重要,通过对UML动态图和静态图的描述,可以映射到领域模型中。

    从服务层刚才讲到了DTO模型,这里需要一个机制将DTO转化为领域模型,所以产生了DTO映射层(DTOMapper)。

    另外业务层还包括核心中间件技术,包括第三方组件,以及工作流引擎等等。

    80ad06165c5dde03adbaef02a3eeb0b6.png

    业务层需要考虑到一些与数据访问层交互的设计模式,模式中包括事物脚本模式、表模块模式、活动记录模式、领域模型模式。

    事物脚本模式是通过方法来执行业务流程,它是一个过程式模型,事物脚本的每个方法都有一个特定的事物脚本,它侧重于业务上一系列流程上的顺序操作,它实现起来很简单,但是它有个致命的缺点就是它会造成很多重复的代码。

    表模块模式比起事物脚本模式,具有一定的结构,它的思想也很简单,每个数据表都定义一个业务组件(实体类,实体操作类),在.NET中更多的使用DataSet作为表模型的数据交互。但是它也有一个缺点就是它是从数据库驱动它不适合于大量的数据表以及数据表之间的复杂关系。

    活动记录模式中的对象中,可以包含数据和方法。它接近于数据表的结构,它的对象中执行方法中可以包含CRUD操作,验证算法,以及其他的计算功能。一般来说,领域模型不是太复杂,活动记录模式是个好选择。当然他也存在问题,同样地,它对于复杂的业务上,维护的成本也很高,并且如果需求变更导致数据库修改,就需要调整记录对象模型中的相关代码。

    经典应用:LINQ-TO-SQL以及Castle ActiveRecord。

    领域模型模式是从领域驱动设计中衍生来的,它是以业务为核心的设计模式。它对于复杂的业务逻辑,相当适用。前三种方式使用的是以数据驱动方式,数据驱动方式特点简单,但是当系统到了一定的规模后,就会到难以维护的程度。

    59f2a477a935e8164e4c4f418e26f6a4.png

    数据访问层的目的很明确,主要作为提供数据持久化的功能,包括数据的读取和写入,另外还必须包括事务处理,并发控制等等。

    操作数据库的方法可以有两种方式:ORM方式、http://ADO.NET方式。

    ORM可以采用一些第三方的ORM框架来实现,http://ADO.NET采用http://ASP.NET自带的数据库操作来实现。

    不同的数据库具有不同的持久化实现,因此这里添加一个存储仓库接口层,来适应不同的数据库实现,这里你可以使用IOC依赖注入方式进行数据库选型,可以利用Unity、http://Spring.NET、Castle的IOC容器等等。

    36e7cd823678975c7430f103f4709bfd.png

    最后各个层中都可以依赖于公共基础设施层。

    公共基础设施层可以包括Common通用模块、Logging日志模块、Exception异常模块、Configuration配置模块、DI依赖注入模块、单元测试模块以及第三方组件(例如NHibernate、http://Sprint.NET、Castle、Quartz计划任务等等)

    最终图:

    28cd6ab78b35e34b0281a06034657d1f.png

    总结:项目类型、项目规模以及业务上的需求,都影响着系统架构的设计,系统架构并不是一层不变的,没有最好的架构,只有更好的架构,并且从项目中多思考系统的扩展性。

    ※更多文章和资料|点击后方文字直达 ↓↓↓ 100GPython自学资料包 阿里云K8s实战手册 [阿里云CDN排坑指南]CDN ECS运维指南 DevOps实践手册 Hadoop大数据实战手册 Knative云原生应用开发指南 OSS 运维实战手册 云原生架构白皮书 Zabbix企业级分布式监控系统源码文档 Linux&Python自学资料包 10G面试题戳领

    展开全文
  • 架构 背景: 项目的引用关系是:StructWed->BLL,Model;BLL->DAL,Model;DAL->Model。下面我们来演示一下程序流程,假设我们的数据库有一张订单表Order表,我们的业务是针对Order表进行的增删改查,...

     

     

    三层架构

    背景:

        项目的引用关系是: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

    转载于:https://www.cnblogs.com/youguess/p/10188550.html

    展开全文
  • 在我们刚开始学习架构的时候,首先会想到分层的概念,分层架构比较经典的是架构,那么,什么是架构呢?它包括表现层、业务层、数据访问层;而对于一个新手来说,从抽象意义上的架构,逻辑上就划分为个...
    在我们刚开始学习架构的时候,首先会想到分层的概念,分层架构比较经典的是三层架构,那么,什么是三层架构呢?它包括表现层、业务层、数据访问层;而对于一个新手来说,从抽象意义上的三层架构,逻辑上就划分为三个层。ffa7fc07fdb23bf0d76b939b593d8b99.png这个是最基本的三层架构模式。表现层充当系统的界面呈现以及UI逻辑的角色,也就是说,UI(用户界面)属于表现层;举一个对于asp.net WebForm来说,人们喜欢把对于UI的控制逻辑(服务器控件的读取、设置、事件等等)写在页面的后置隐藏代码中,并且依赖业务逻辑层。当然,服务器控件支持数据绑定的功能,可以通过数据源进行绑定控件。这样就可以节省在后置隐藏中的代码。 因此,我们就可以把表现层分为UI用户界面以及UI逻辑:d8465ce30f831a53e5725819e1e01d42.pngUI用户界面的职责只是作为数据输入和输出后的展示工作。UI逻辑的职责是负责业务逻辑层以及UI用户界面之间的数据交互,并且尽可能地让UI逻辑不依赖于UI技术。其中UI用户界面的实现方式有很多,包括ASP.NET、WinForm、WPF、Silverlight、移动Web、智能设备等等。dd4d4fd6eb8b58d84fcfb9a87b6a179b.png将表现层中UI页面和UI逻辑分离的策略中,当前使用最多的两种模式是MVC模式和MVP模式。MVC模式,即模型-视图-控制器模式,通过视图触发并执行某个操作,调用控制器,通过控制器去操作业务层,最终返回模型,在视图中进行展示。这里的模型可以是一个领域模型(DM),也可以是一个数据迁移对象(DTO)。MVP模式,即模型-视图-展示器模式,和MVC模式有点像,不同的是MVP中视图和模型是被完全分离出来的,视图中定义一个接口,而展示器通过调用该接口的方法以控制视图。因此,视图和模型是松散的,展示器也充当了一个控制器的角色,同时它也不依赖于UI技术。另外再介绍一种模式PM(Preentation Model),它可以说是MVP的变体,在PM中,视图不定义接口,这里的模型只是表示视图状态的类,视图中的元素被直接绑定到模型属性上。例如在WPF中,WPF就先天的具有数据双向绑定机制以及事件通知属性机制。所以它特别适用于WPF,Sliverlight等等。4aaec559b2162d59e420f958d7ebfc0e.png在开始业务层之前,不得不说一个前提,在一个小型项目中,直接让表现层调用业务层,足以解决所有问题。但是,当项目大到使用多种表现形式,如使用了各种UI技术、ASP.NET、WPF、移动设备等等,就要考虑在你的表现层和业务层之间增加一个层,以至于让表现层和业务层解耦,因为业务层作为一个业务中间件的平台,最好不要暴露于表现层中,这个层就是传说中的服务层。架构图又演化为:f739bf1f5ff72215fa9b9bdebf8452ab.png服务层实际上并不执行任何具体的工作,其功能在于组织各个业务对象,服务层将业务层所有的细节对表现层都隐藏起来,服务器将组织业务逻辑层中的组件,并且通过数据迁移对象(DTO)与表现层交互,因此就产生一个DTO模型。为了实现服务的可重用性,需要使用服务接口,表现层通过规定的接口访问功能。服务的实现继承服务接口,而服务的实现专注于业务层的调用。0117def237a6c55fb6511051517c1d24.png对于服务层,常用的方法包括Web服务、.NET Remoting、Rest以及WCF技术。本人比较建议使用WCF作为服务,因为可以方便地通过配置达到远程调用服务的目的。服务层消除了两个表现层和业务层之间的耦合,服务层可以实现一个远程接口,达到多UI技术甚至多平台上的通信。当然增加服务层也有缺点,假如使用WCF服务,会增加系统的调用开销,进而影响性能。475262a53b4cbdee328947e72a10d904.png业务层中包含系统所需要业务过程上的实现,并与下层的数据访问层交互。我们通常也叫做业务层叫做业务逻辑层,但我认为业务逻辑层是属于业务层的一方面,业务逻辑更专注于业务上逻辑算法的实现。因为业务层还可以包括其他的方面。业务层必须包括对业务实体尽心建模的对象模型,表达了客户的所有策略和需求的业务规则,因此就产生了领域模型。(PS:如果这里你不使用领域模型,那么需要采用业务规则层进行业务功能上的业务规则的验证和控制)领域模型包括对实体的属性定义,方法定义以及实体与实体之间的关系。从这个角度上看,UML建模至关重要,通过对UML动态图和静态图的描述,可以映射到领域模型中。从服务层刚才讲到了DTO模型,这里需要一个机制将DTO转化为领域模型,所以产生了DTO映射层(DTOMapper)。另外业务层还包括核心中间件技术,包括第三方组件,以及工作流引擎等等。1b2281c9b4ede7884543f0b73d29d9bd.png业务层需要考虑到一些与数据访问层交互的设计模式,模式中包括事物脚本模式、表模块模式、活动记录模式、领域模型模式。事物脚本模式是通过方法来执行业务流程,它是一个过程式模型,事物脚本的每个方法都有一个特定的事物脚本,它侧重于业务上一系列流程上的顺序操作,它实现起来很简单,但是它有个致命的缺点就是它会造成很多重复的代码。表模块模式比起事物脚本模式,具有一定的结构,它的思想也很简单,每个数据表都定义一个业务组件(实体类,实体操作类),在.NET中更多的使用DataSet作为表模型的数据交互。但是它也有一个缺点就是它是从数据库驱动它不适合于大量的数据表以及数据表之间的复杂关系。活动记录模式中的对象中,可以包含数据和方法。它接近于数据表的结构,它的对象中执行方法中可以包含CRUD操作,验证算法,以及其他的计算功能。一般来说,领域模型不是太复杂,活动记录模式是个好选择。当然他也存在问题,同样地,它对于复杂的业务上,维护的成本也很高,并且如果需求变更导致数据库修改,就需要调整记录对象模型中的相关代码。经典应用:LINQ-TO-SQL以及Castle ActiveRecord。领域模型模式是从领域驱动设计中衍生来的,它是以业务为核心的设计模式。它对于复杂的业务逻辑,相当适用。前三种方式使用的是以数据驱动方式,数据驱动方式特点简单,但是当系统到了一定的规模后,就会到难以维护的程度。eb073d604346e0c3a80eb89f059bf0d0.png数据访问层的目的很明确,主要作为提供数据持久化的功能,包括数据的读取和写入,另外还必须包括事务处理,并发控制等等。操作数据库的方法可以有两种方式:ORM方式、ADO.NET方式。ORM可以采用一些第三方的ORM框架来实现,ADO.NET采用ASP.NET自带的数据库操作来实现。不同的数据库具有不同的持久化实现,因此这里添加一个存储仓库接口层,来适应不同的数据库实现,这里你可以使用IOC依赖注入方式进行数据库选型,可以利用Unity、Spring.NET、Castle的IOC容器等等。015a44e4ecc93a470aeb8ddbb3b507a1.png最后各个层中都可以依赖于公共基础设施层。公共基础设施层可以包括Common通用模块、Logging日志模块、Exception异常模块、Configuration配置模块、DI依赖注入模块、单元测试模块以及第三方组件(例如NHibernate、Sprint.NET、Castle、Quartz计划任务等等)最终图:3ed7e54ac167aa1346ada9ea60ab529e.png总结:项目类型、项目规模以及业务上的需求,都影响着系统架构的设计,系统架构并不是一层不变的,没有最好的架构,只有更好的架构,并且从项目中多思考系统的扩展性。

    转载源 | 博客园

    721a38f7fa70ff01b04ea771a0b29a1b.png  关注“架构之美”   -

    07f5bef52ffcb0de46da0291768ff512.png

    展开全文
  • 企业级系统架构

    2013-10-11 14:29:19
    谈谈对于企业级系统架构的理解 在我们刚开始学习架构的时候,首先会想到分层的概念,分层架构比较经典的是架构,那么,什么是架构呢?它包括表现层,业务层,数据访问层;而对于一个新手来说,从抽象...

    本文转载自Leepy's Blogs 博客园。

    谈谈对于企业级系统架构的理解

    在我们刚开始学习架构的时候,首先会想到分层的概念,分层架构比较经典的是三层架构,那么,什么是三层架构呢?它包括表现层,业务层,数据访问层;而对于一个新手来说,从抽象意义上的三层架构,逻辑上就划分为三个层。

    image

    这个是最基本的三层架构模式。

    表现层充当系统的界面呈现以及UI逻辑的角色,也就是说,UI(用户界面)属于表现层;

    举一个对于asp.net WebForm来说,人们喜欢把对于UI的控制逻辑(服务器控件的读取、设置、事件等等)写在页面的后置隐藏代码中,并且依赖业务逻辑层。当然,服务器控件支持数据绑定的功能,可以通过数据源进行绑定控件。这样就可以节省在后置隐藏中的代码。

    因此,我们就可以把表现层分为UI用户界面以及UI逻辑:

    image

    UI用户界面的职责只是作为数据输入和输出后的展示工作。

    UI逻辑的职责是负责业务逻辑层以及UI用户界面之间的数据交互,并且尽可能地让UI逻辑不依赖于UI技术

    其中UI用户界面的实现方式有很多,包括ASP.NET,WinForm,WPF,Silverlight,移动Web,智能设备等等。

    image

    将表现层中UI页面和UI逻辑分离的策略中,当前使用最多的两种模式是MVC模式和MVP模式。

    MVC模式,即模型-视图-控制器模式,通过视图触发并执行某个操作,调用控制器,通过控制器去操作业务层,最终返回模型,在视图中进行展示。这里的模型可以是一个领域模型(DM),也可以是一个数据迁移对象(DTO)。

    MVP模式,即模型-视图-展示器模式,和MVC模式有点像,不同的是MVP中视图和模型是被完全分离出来的,视图中定义一个接口,而展示器通过调用该接口的方法以控制视图。因此,视图和模型是松散的,展示器也充当了一个控制器的角色,同时它也不依赖于UI技术。

    另外再介绍一种模式PM(Preentation Model),它可以说是MVP的变体,在PM中,视图不定义接口,这里的模型只是表示视图状态的类,视图中的元素被直接绑定到模型属性上。例如在WPF中,WPF就先天的具有数据双向绑定机制以及事件通知属性机制。

    所以它特别适用于WPF,Sliverlight等等。

    image

    在开始业务层之前,不得不说一个前提,在一个小型项目中,直接让表现层调用业务层,足以解决所有问题。但是,当项目大到使用多种表现形式,如使用了各种UI技术,ASP.NET,WPF,移动设备等等,就要考虑在你的表现层和业务层之间增加一个层,以至于让表现层和业务层解耦,因为业务层作为一个业务中间件的平台,最好不要暴露于表现层中,这个层就是传说中的服务层。架构图又演化为:

    image

    服务层实际上并不执行任何具体的工作,其功能在于组织各个业务对象,服务层将业务层所有的细节对表现层都隐藏起来,服务器将组织业务逻辑层中的组件,并且通过数据迁移对象(DTO)与表现层交互,因此就产生一个DTO模型。

    为了实现服务的可重用性,需要使用服务接口,表现层通过规定的接口访问功能。服务的实现继承服务接口,而服务的实现专注于业务层的调用

    image

    对于服务层,常用的方法包括Web服务、.NET Remoting、Rest以及WCF技术。

    本人比较建议使用WCF作为服务,因为可以方便地通过配置达到远程调用服务的目的。

    服务层消除了两个表现层和业务层之间的耦合,服务层可以实现一个远程接口,达到多UI技术甚至多平台上的通信。

    当然增加服务层也有缺点,假如使用WCF服务,会增加系统的调用开销,进而影响性能。

    image

    业务层中包含系统所需要业务过程上的实现,并与下层的数据访问层交互。

    我们通常也叫做业务层叫做业务逻辑层,但我认为业务逻辑层是属于业务层的一方面,业务逻辑更专注于业务上逻辑算法的实现。因为业务层还可以包括其他的方面。

    业务层必须包括对业务实体尽心建模的对象模型,表达了客户的所有策略和需求的业务规则,因此就产生了领域模型

    (PS:如果这里你不使用领域模型,那么需要采用业务规则层进行业务功能上的业务规则的验证和控制)

    领域模型包括对实体的属性定义,方法定义以及实体与实体之间的关系。从这个角度上看,UML建模至关重要,通过对UML动态图和静态图的描述,可以映射到领域模型中。

    从服务层刚才讲到了DTO模型,这里需要一个机制将DTO转化为领域模型,所以产生了DTO映射层(DTOMapper)。

    另外业务层还包括核心中间件技术,包括第三方组件,以及工作流引擎等等。

    image

    业务层需要考虑到一些与数据访问层交互的设计模式,模式中包括事物脚本模式、表模块模式、活动记录模式、领域模型模式。

    事物脚本模式是通过方法来执行业务流程,它是一个过程式模型,事物脚本的每个方法都有一个特定的事物脚本,它侧重于业务上一系列流程上的顺序操作,它实现起来很简单,但是它有个致命的缺点就是它会造成很多重复的代码。

    表模块模式比起事物脚本模式,具有一定的结构,它的思想也很简单,每个数据表都定义一个业务组件(实体类,实体操作类),在.NET中更多的使用DataSet作为表模型的数据交互。但是它也有一个缺点就是它是从数据库驱动它不适合于大量的数据表以及数据表之间的复杂关系。

    活动记录模式中的对象中,可以包含数据和方法。它接近于数据表的结构,它的对象中执行方法中可以包含CRUD操作,验证算法,以及其他的计算功能。一般来说,领域模型不是太复杂,活动记录模式是个好选择。当然他也存在问题,同样地,它对于复杂的业务上,维护的成本也很高,并且如果需求变更导致数据库修改,就需要调整记录对象模型中的相关代码。

    经典应用:LINQ-TO-SQL以及Castle ActiveRecord。

    领域模型模式是从领域驱动设计中衍生来的,它是以业务为核心的设计模式。它对于复杂的业务逻辑,相当适用。前三种方式使用的是以数据驱动方式,数据驱动方式特点简单,但是当系统到了一定的规模后,就会到难以维护的程度。

    image

    数据访问层的目的很明确,主要作为提供数据持久化的功能,包括数据的读取和写入,另外还必须包括事务处理,并发控制等等。

    操作数据库的方法可以有两种方式,ORM方式,ADO.NET方式。

    ORM可以采用一些第三方的ORM框架来实现,ADO.NET采用ASP.NET自带的数据库操作来实现。

    不同的数据库具有不同的持久化实现,因此这里添加一个存储仓库接口层,来适应不同的数据库实现,这里你可以使用IOC依赖注入方式进行数据库选型,可以利用Unity、Spring.NET、Castle的IOC容器等等。

    image

    最后各个层中都可以依赖于公共基础设施层

    公共基础设施层可以包括Common通用模块,Logging日志模块,Exception异常模块,Configuration配置模块,DI依赖注入模块,单元测试模块以及第三方组件(例如NHibernate、Sprint.NET、Castle、Quartz计划任务等等)

    最终图:

    image

    总结:项目类型、项目规模以及业务上的需求,都影响着系统架构的设计,系统架构并不是一层不变的,没有最好的架构,只有更好的架构,并且从项目中多思考系统的扩展性。文中对于架构的分析,只是从通常的角度上去考虑,在项目中,您还需要根据实际情况去做调整。

    展开全文
  • 分享交流 书店管理系统 系统架构 public static bool AddUser(User user) { string sql = "INSERT USERS (loginid, loginpwd, name, address, phone, mail, userroleId, UserStateId" + "VALUES @LoginId@LoginPwd@...
  • 架构, 功能完善 美工优雅 架构,著名企业级单实例模式
  • 1.1关于架构架构这个词从它的出现后,就有许许多多的程序员、架构师们激烈地讨论着它的发展,但是架构一词的出现,却是随着架构的出现才出现的。当然,目前应用架构开发也正是业界最关注的主题。那么这里我们...
  • 第一次接触企业级别的程序,第一感觉是非常繁琐复杂,本来实现一个很简单的功能,比如该项目实现的功能,用最简单的方法也能实现,为何要大费周章的使用企业级架构呢? 为何?在我自己的理解 1.低耦合(为前后端分离...
  • 好下面搭建我们的层构,如图:    项目的框架与上一篇基本一致。项目的引用关系: StructUI->Common,Model,BLL; BLL -> Model,IDAL,Common,Factory;DAL-> IDAL,Model。再次提醒各位,我们在BLL层并没有...
  • 企业级网络架构

    2019-12-28 08:31:54
    目录 层交换机 层交换机使用过程: 连接外网 动态路由 ospf 协议,开放最短路径优先协议 ospf区域 ...层交换机 ...使用层交换技术实现VLAN间通信 ...层交换=二层交换+层转发 层...
  • 1.架构介绍 1.1关于架构 架构这个词从它的出现后,就有许许多多的程序员、架构师们激烈地讨论着它的发展,但是架构一词的出现,却是随着架构的出现才出现的。当然,目前应用架构开发也正是业界最...
  • ASP.NET企业级架构开发技术与案例教程,ASP.NET WebForm、抽象工厂模式层架构、ASP.NET MVC、NHibernate、Spring.Net、ORM、IoC
  • 搭建好了lnmp架构 真机( 172.25 .0 .250 ) 测试 1.在server中,在已经获得论坛包的基础上,解压论坛包 cd /usr/local/lnmp/nginx/html 2.在浏览器访问,论坛的地址 点击左下角的现在就开始 提示 ...
  • 企业架构实验

    2021-01-22 23:03:12
    企业网三层架构实验实验要求实验分析三级目录 实验要求 1、内网IP地址172.16.0.0/16 合理分配。 2、SW1/2之间互为备份。 3、VRRP/STP/VLAN/TRUNK均使用。. 4、所有PC通过DHCP获取ip地址。 实验分析 对于新建一个...
  • 架构与设计模式思想部署企业级数据库业务系统开发 - Asp.net源码交流论坛 - ASP.net源码|...用架构与设计模式思想部署企业级数据库业务系统开发 1关于架构架构这个词从它的出现后,就有许许多...
  • 全球企业对思杰所代表的集中管控安全体系的广泛采纳 某...企业IT应如何应变呢 端到端虚拟化 云计算的基石 随需应变业务永续的内外网安全隔离架构 应用与桌面虚拟化实现集中管控 PC 虚拟化 完美的用户体验保障 HDX 技术
  • 在我们刚开始学习架构的时候,首先会想到分层的概念,分层架构比较经典的是架构,那么,什么是架构呢?它包括表现层,业务层,数据访问层;而对于一个新手来说,从抽象意义上的架构,逻辑上就划分为个...
  • 源码阅读篇 Spring重要接口详解 BeanFactory继承体系 ...AutowireCapableBeanFactory、HierarchicalBeanFactory、ListableBeanFactory3个子接口继承了它,进行功能上的增强,这3个接口称为二接口 Configurab...
  • 在我们刚开始学习架构的时候,首先会想到分层的概念,分层架构比较经典的是架构,那么,什么是架构呢?它包括表现层,业务层,数据访问层;而对于一个新手来说,从抽象意义上的架构,逻辑上就划分为个...
  • ASP.NET典型架构企业级医药行业ERP系统实战(8大模块22个子系统,价值3000万)  课程讲师:Tiger 课程分类:.net 适合人群:高级 课时数量:192课时 更新程度:完毕 我这里有一套课程和大家分享,我的qq是...
  •  下面我们来看一看目前版本的数据访问层相对于上一篇的数据访问层的改进,对照我们上一篇的项目结构(下图),我们发现在的数据访问层的DAL项目被干掉了,AdoDal,EFDal与DALFactory这个新项目被添加进来了。...
  • 架构企业站源码 简单的ASP.NET 架构的DEMO 产品类别是无限级的
  • 架构与设计模式思想部署企业级数据库业务系统开发.doc
  • // 第个参数:代理对象的执行处理器 return object; } /** * 代理对象会执行的方法 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{ Method ...
  • @Override public void init() { // In 2.0 XSD as well as in 2.1 XSD. // <aop:config></aop:config>对应的BeanDefinitionParser registerBeanDefinitionParser("config", new ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,450
精华内容 980
关键字:

企业三级架构