本章内容主要包括两个方面,一、是框架分层(控制器、业务对象、实体、Dao)的详细说明,二、是对比常用三层结构的区别和优势;

本文要点:

1.框架中的各个分层详细说明

2.对比常用三层结构的区别和优势

3.分享两个项目中的小经验

4.网络资料

我们先看一下前面实例中的解决方案目录:

我们再看各层之间的调用关系:

上图描叙的控制器有四种方式来操作数据库,

1)控制器调用实体,通过框架中的ORM来实现单表的操作

2)控制器直接操作数据库对象(oleDB),通过编写SQL语句访问数据库

3)控制器通过调用Dao操作数据库

4)控制器调用业务对象,业务对象再调用Dao操作数据库

还有就是每一层在程序结构中承担的角色;

一、Dao

数据访问对象,新建一个Dao必须继承继承框架中的AbstractDao对象,AbstractDao对象中封装了数据库操作对象oleDb,所以Dao中的方法都是直接编写SQL语句操作数据库;

public class BookDao : EFWCoreLib.CoreFrame.BusinessArchitecture.AbstractDao
{
public DataTable GetBooks(string searchChar, int flag)
{
string strsql = @"SELECT * FROM dbo.Books WHERE BookName LIKE '%{0}%' AND Flag={1}";
strsql = string.Format(strsql, searchChar, flag);
return oleDb.GetDataTable(strsql);
}
   }

上面代码是实现对Sqlserver数据库的操作,如果要实现不同数据库的操作,如:Oracle、DB2等,要如何实现?很简单,先创建IBookDao接口,再分别实现SqlBookDao和OracleBookDao,控制器访问Dao只需调用IBookDao接口就行了,而最后操作哪个数据库的Dao在EFWUnity.config配置文件中配置好。

IBookDao接口

  public interface IBookDao
{
System.Data.DataTable GetBooks(string searchChar, int flag);
   }

SqlBookDao对象

 public class SqlBookDao : EFWCoreLib.CoreFrame.BusinessArchitecture.AbstractDao, Books.Dao.IBookDao
{
public DataTable GetBooks(string searchChar, int flag)
{
string strsql = @"SELECT * FROM dbo.Books WHERE BookName LIKE '%{0}%' AND Flag={1}";
strsql = string.Format(strsql, searchChar, flag);
return oleDb.GetDataTable(strsql);
}
   }

OracleBookDao对象

public class OracleBookDao : EFWCoreLib.CoreFrame.BusinessArchitecture.AbstractDao, Books.Dao.IBookDao
{
public DataTable GetBooks(string searchChar, int flag)
{
string strsql = @"SELECT * FROM Books WHERE BookName LIKE '%{0}%' AND Flag={1}";
strsql = string.Format(strsql, searchChar, flag);
return oleDb.GetDataTable(strsql);
}
   }

EFWUnity.config配置文件

控制器中通过NewDao<>操作方法,创建配置的SqlBookDao对象

综合上述,不同数据库Dao结构设计如下:

二、Entity实体

实体代码都是用工具,根据数据库表结构信息生成的;所有实体都必须继承框架中的AbstractEntity对象,而实体与数据库表之间的映射不需要另外xml配置文件,而是利用自定义标签实现ORM映射;TableAttribute标签映射实体类名与数据库表,ColumnAttribute标签映射实体属性与数据库表字段。一个实体映射到多个表也可以,直接类名上配置多个TableAttribute标签和属性上配置多个ColumnAttribute标签,不过要用标签的Alias参数区分。

三、ObjectModel业务对象

业务对象在书籍管理实例并没有建此对象,因为业务太简单了,只有当业务流程很复杂或范围涉及广的情况,就可以考虑建一些业务对象来解决这些问题;所有业务对象必须继承框架中的AbstractBusines对象,业务对象中不能直接操作数据库,必须通过Dao来访问。另外就是如果多个业务对象是用来解决同一个问题,一般我们使用工厂模式来设计,在框架中可以使用EFWUnity.config配置文件进行业务对象映射;

四、Controller控制器,包括WebController、WinController、WcfController、WcfClientController

控制器分为3种模式,不同模式分别建控制器。控制器在程序结构中的作用就是承上启下,比如WebController控制器,就是把调用逻辑层返回的数据结构转换为统一Json字符串传递给界面JqueryEasyUI。而不同的界面框架则需要对框架中的Webcontroller进行扩展,以后我们会详细讲解各种控制器的实现;

还有就是Controller中提供了数据库的操作对象OleDB,允许控制器直接编写SQL语句操作数据库,为什么要放开此功能,这也是在项目中遇到的实际情况而不得不妥协的一种设计;

同样所有控制器也都必须框架中的基类控制器,基于JqueryEasyUI的Webcontroller继承AbstractJqueryController对象,WinController继承BaseController对象,wcfController继承JsonWCFController对象;wcfClientController继承BaseWCFClientController对象;

再就是控制器暴露给界面UI,还必须加上控制器的自定义标签,WebController的WebController和WebMethod,WinController的Menu,wcfClientController的WCFController和WCFMethod;

        通过上面的介绍,应该对EnterpriseFrameWork框架的分层结构有一定得了解,下面我们讨论一下,与常用三层结构的区别与优势?

软件分层意义主要就包括解耦和复用,也许还能让代码维护与扩展更方便;三层结构分别包括界面层、逻辑层和数据层。EnterpriseFrameWork框架中的分层也可以说是三层,只是叫法与承担的职责不一样,并且EnterpriseFrameWork框架中的分层可以随时变化的,不同情况有4种方式对分层进行调整,所以EnterpriseFrameWork框架分层的兼容性强。有哪些不同情况,可以总结为两种,一是根据具体功能的难易程度,二是根据开发人员的代码水平

我们对比一下PetShop项目的程序结构:

PetShop项目名称及描述:(实现步骤为:4-3-6-5-2-1) 
1、WEB=表示层 
2、BLL=业务逻辑层
3、IDAL=数据访问层接口定义 
4、Model=业务实体 
5、DALFactory=数据层的抽象工厂(创建反射) 
6、SQLServerDAL=SQLServer数据访问层 / OracleDAL=Oracle数据访问层 DBUtility 数据库访问组件基础类

其中3中的IDAL对应EnterpriseFrameWork框架中的Dao接口,Model对应框架中的实体,SQLServerDAL和OracleDAL对应不同数据库Dao;而不同的有5中的DALFactory在框架中是不需要的,只需配置文件中配置即可;2中的BLL也职责不一样,框架中更趋向领域模型的设计;1中的WEB表示层,框架中单独把Controller控制器分出来独立一层;所以对比两者发现其思想还是差别比较大的,个人觉得EnterpriseFrameWork框架除了在程序代码的解耦,更在业务、项目等实际情况方面更加合适;

接着再讨论一下:贫血模型与充血模型?

贫血模型:是指领域对象里只有get和set方法,或者包含少量的CRUD方法,所有的业务逻辑都不包含在内而是放在Business Logic层。

充血模型:层次结构和上面的差不多,不过大多业务逻辑和持久化放在Domain Object里面,Business Logic(业务逻辑层)只是简单封装部分业务逻辑以及控制事务、权限等。

对这两种模型的使用个人感觉比较深刻,以前还不知道这种写法是贫血模型,表生成所有实体,再就是调用实体的N个逻辑对象,这样的代码就越写越过程化,基本上一个系统分成几个逻辑对象就完成了,没有了对象的概念;后来就觉得这样不对,就把实体扩展成一个完整的业务对象,实现对这个实体的所有业务操作方法;这样刚开始还蛮有感觉,但后来越做越别扭,一是很多实体根本没有业务操作,还有就是一个业务操作会跨多个实体;在实体上来补充业务操作方法本来就不太合理,因为表结构的设计本来就不是基于面向对象的;所以后来就演变为现在EnterpriseFrameWork框架中ObjectModel这种模型,我叫做领域对象模型;简单的业务走第一种模式,复杂的业务就必须分析出领域模型并设计业务对象;

最后分享两个项目中的小经验,一个是与大学高校合作开发项目、另一个是小公司老板的见解;

与大学高校合作开发一个不算太复杂的项目,公司方负责需求的收集与分析,高校针对需求进行设计与开发;高校由一个研究生导师带队,也没用什么技术框架,就是常用的三层结构,合作的过程就不讲了,反正就是最后到我接手维护代码的时候就感觉到这个系统的坑人之处;首先不算复杂的系统项目建了十多个,找代码文件很难找,再就是每改一个小地方要改多个文件从界面层改到数据层;最受不了的就是代码的阅读与调试相当麻烦,每层之间又通过一个工厂反射类名方法名调用;最后我们得出的结论就是在实际项目千万不能交给高校开发,他们可以搞一些研究项目,做的时候又没有考虑到一些实际情况;

小公司老板的见解。一朋友自己做老板创业,懂点php网页开发,在学校招了几个刚毕业生准备研发一个新产品,要我帮忙他们搭建系统框架,我推荐最早框架给他们使用,那时候在Controller中并没有OleDB操作数据库;我先把系统的核心业务开发完成,招的几个毕业生就在此基础上继续完善系统,刚开始我在的时候还好,有什么不明白的我帮忙解决,后来我抽出来后,他们做着做着问题就暴露出来了,一个简单的功能很久都搞不出来,新产品讲究的就是速度嘛,马上要给客户看的;所以朋友急了开始找原因,虽然朋友就会个php网页制作,但通过与几个毕业生深入沟通,他发现程序分层太复杂了,做一个功能要画界面,写控制器、写业务对象、写Dao才能完成,更难的他们根本对逻辑层的控制器、业务对象、Dao理解不了,所以一定要他们这样用就经常搞出一些莫名其妙的问题;朋友就说为什么不能直接在控制器中写sql语句,这样开发起来多简单?我就说这样放开不行,会破坏整个程序的分层结构,以后代码的维护、扩展都会有问题,但我的这些以后说服不了他,他觉得这些以后版本可以优化,现在就是要马上出来;最后只要在控制器也开放了Oledb操作数据库;

网络上对于三层结构的解释

数据访问层:有时候也称为是持久层,其功能主要是负责数据库的访问。简单的说法就是实现对数据表的Select,Insert,Update,Delete的操作。如果要加入ORM的元素,那么就会包括对象和数据表之间的mapping,以及对象实体的持久化。在PetShop的数据访问层中,并没有使用ORM,从而导致了代码量的增加,可以看作是整个设计实现中的一大败笔。

业务逻辑层:是整个系统的核心,它与这个系统的业务(领域)有关。以PetShop为例,业务逻辑层的相关设计,均和网上宠物店特有的逻辑相关,例如查询宠物,下订单,添加宠物到购物车等等。如果涉及到数据库的访问,则调用数据访问层。

表示层:是系统的UI部分,负责使用者与整个系统的交互。在这一层中,理想的状态是不应包括系统的业务逻辑。表示层中的逻辑代码,仅与界面元素有关。在PetShop中,是利用ASP.Net来设计的,因此包含了许多Web控件和相关逻辑。

分层的好处
1、开发人员可以只关注整个结构中的其中某一层;
2、可以很容易的用新的实现来替换原有层次的实现;
3、可以降低层与层之间的依赖;
4、有利于标准化;
5、利于各层逻辑的复用。

概括来说,分层式设计可以达至如下目的:分散关注、松散耦合、逻辑复用、标准定义。

分层的坏处:

1、降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。

2、有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。 

十、EnterpriseFrameWork框架的分层架构及意义(控制器、业务对象、实体、Dao之间关系)的更多相关文章

  1. 十一、EnterpriseFrameWork框架的分层与系统业务的结合

    上章详细讲了EnterpriseFrameWork框架中的每个分层,这都是从技术层面来说明,也就是我们知道怎么来建一个控制器或一个业务对象,但开发过程中应该建一个什么样的控制器或业务对象了?本章的主要 ...

  2. 十八、【开源】EnterpriseFrameWork框架核心类库之Winform控制器

    回<[开源]EnterpriseFrameWork框架系列文章索引> EFW框架源代码下载:http://pan.baidu.com/s/1qWJjo3U EFW框架中的WinContro ...

  3. Spring:Spring优势——分层架构简介

    Spring框架采用分层架构,根据不同的功能被划分成了多个模块,这些模块大体可分为 Data Access/Integration.Web.AOP.Aspects.Messaging.Instrume ...

  4. 应用程序框架实战十五:DDD分层架构之领域实体(验证篇)

    在应用程序框架实战十四:DDD分层架构之领域实体(基础篇)一文中,我介绍了领域实体的基础,包括标识.相等性比较.输出实体状态等.本文将介绍领域实体的一个核心内容——验证,它是应用程序健壮性的基石.为了 ...

  5. 应用程序框架实战十八:DDD分层架构之聚合

    前面已经介绍了DDD分层架构的实体和值对象,本文将介绍聚合以及与其高度相关的并发主题. 我在之前已经说过,初学者第一步需要将业务逻辑尽量放到实体或值对象中,给实体“充血”,这样可以让业务逻辑高度内聚, ...

  6. 应用程序框架实战十四:DDD分层架构之领域实体(基础篇)

    上一篇,我介绍了自己在DDD分层架构方面的一些感想,本文开始介绍领域层的实体,代码主要参考自<领域驱动设计C#2008实现>,另外参考了网上找到的一些示例代码. 什么是实体 由标识来区分的 ...

  7. 应用程序框架实战十六:DDD分层架构之值对象(介绍篇)

    前面介绍了DDD分层架构的实体,并完成了实体层超类型的开发,同时提供了验证方面的支持.本篇将介绍另一个重要的构造块——值对象,它是聚合中的主要成分. 如果说你已经在使用DDD分层架构,但你却从来没有使 ...

  8. 如何在Visual Studio 2017中使用C# 7+语法 构建NetCore应用框架之实战篇(二):BitAdminCore框架定位及架构 构建NetCore应用框架之实战篇系列 构建NetCore应用框架之实战篇(一):什么是框架,如何设计一个框架 NetCore入门篇:(十二)在IIS中部署Net Core程序

    如何在Visual Studio 2017中使用C# 7+语法   前言 之前不知看过哪位前辈的博文有点印象C# 7控制台开始支持执行异步方法,然后闲来无事,搞着,搞着没搞出来,然后就写了这篇博文,不 ...

  9. Apworks框架实战(四):使用Visual Studio开发面向经典分层架构的应用程序:从EasyMemo案例开始

    时隔一年,继续我们的Apworks框架之旅.在接下来的文章中,我将逐渐向大家介绍如何在Visual Studio中结合Apworks框架,使用ASP.NET Web API和MVC来开发面向经典分层架 ...

随机推荐

  1. ASP.NET MVC简单编程之(二)经典路由篇

    话题:请求从路由开始 在实际的ASP.NET MVC开发中,URL访问规则----路由的定义是非常重要的.因为任何一个请求都离不开路由.理解它,我们将能理解MVC处理请求的整个过程,灵活地定义系统各种 ...

  2. 如何设置iframe高度自适应,在跨域的情况下能做到吗?

    在页面上使用iframe来动态加载页面内容是网页开发中比较常见的方法.在父页面中给定一个不带滚动条的iframe,然后对属性src指定一个可加载的页面,这样当父页面被访问的时候,子页面可以被自动加载. ...

  3. 使用轻量级ORM Dapper进行增删改查

      项目背景 前一段时间,开始做一个项目,在考虑数据访问层是考虑技术选型,考虑过原始的ADO.NET.微软的EF.NH等.再跟经理讨论后,经理强调不要用Ef,NH做ORM,后期的sql优化不好做,公司 ...

  4. ooj1057: M的整数倍DP

    http://121.249.217.157/JudgeOnline/problem.php?id=1057 1057: M的整数倍 时间限制: 1 Sec  内存限制: 64 MB提交: 130   ...

  5. python常用sql语句

    #coding=utf-8 import MySQLdb conn = MySQLdb.Connect(host = '127.0.0.1',port=3306,user='root',passwd= ...

  6. 如何在windows7上安装启明星系统。

    启明星系统提供多种安装方式.安装包里自带了setup.exe.每个程序的 install下有在线安装(例如请假应用程序为book,则默认为 http://localhost/book/install ...

  7. windows地址转发

    netsh interface portproxy add v4tov4 listenport=8080 connectaddress=192.168.8.108 connectport=8080 把 ...

  8. WPS 文字排版 标题回车后标题号自动增加

    飞思卡来互联网提供全球性的 看了看 风格的呵呵 合格否d合格否的 secure embedded嵌入式解 个国家和地区,注册了成千上万项专利,产品面向 物联网,汽车电子,消费电子,工业及网络设备等市 ...

  9. GTD中落地执行篇

    前面几篇主要是分享GTD对事情进行 ”收集“,“分类”,“组织”.今天主要是想分享“落地执行” 先来看一个案例 (案例 来自于<小强升职记>) 通过这个案例我们看出 1: 当我们通过对事情 ...

  10. 写给程序员和UI--Android的切图标准

    最近总是有人在问我,Android怎么切图啊,怎么适配啊,不只是Android同行,还有很多新手ui设计师. 于是我就写篇文章,根据我们平时的开发经验,简单的介绍一下吧. 如果UI设计师以1920*1 ...