`
zhaomengsen
  • 浏览: 198423 次
  • 性别: Icon_minigender_1
  • 来自: 河北
社区版块
存档分类
最新评论

框架的DTO层介绍

阅读更多

 新年哪里也没有去,呆在家里写了几篇Blog与大家交流一下。平时工作很忙,也难得有时间写点东西。大年三十、初一各发了一往篇,还有那么多的博友陪我一起,像我一样,呵呵。

上面粗粗的介绍了ORM层、业务层。ORM主要是在数据访问,把程序从千篇一率的存储过程调用,从容易出错的Sql语句中解脱出来;业务层主要是规范业务逻辑的组织,简化事务处理,把精力用到处理业务逻辑的刀刃上。对于很小的BS软件,有这两层已经算是可以用了,但如果要考虑到集成、客户端,就会感觉只有这些还是远远不够的,数据处理的灵活性还不够,客户端界面的展示与业务逻辑层耦合的太紧密。

下面就要介绍到数据交换层、服务层、DTO层。我先从DTO层介绍吧,对于DTO层,有的朋友可能会感觉没有存在的必要,多了一层,也或许是这样。复杂度,工作量,对人的要求也高了,成本也高了,等等,都是要考虑的方面。

DTO层,也就是在服务器端和客户端进行沟通的,把业务逻辑层的数据传输到客户端,再把客户端的数据传输到服务器端,既然这样,那么在DTO与逻辑层数据Data之间就存在一个数据交换,数据交换在后面再介绍。DTO的数据要能够支持客户端的数据绑定,可能有的朋友会问,用业务层的数据不可以吗?答案是:如果是在局域网内可以,在广域网上不可以。业务层的数据存在很多数据是延迟加载过来的,在网络上传输数据通常是要求一次把比较多的数据传输过去,也就是通常的粗粒度设计,建立连接等开销太大、时延太大了。另外,客户端需要哪些数据,需要传输哪些数据,业务逻辑层不清楚,业务层只知道我能够提供哪些数据,DTO是知道我需要哪数据,两者所站的角度不同。业务逻辑层的数据相当于数据的提供者,DTO是数据的消费者。朋友们,再发挥一下想像,是不是可以这么理解,因为这个的存在,业务逻辑层设计的时候,可以不考虑界面是如何显示的,只要关心我的业务逻辑就可以,只要我能够提供这些数据就可以了,你是从一个对象里面得到的,还是从几个关联对象里面找到的,还是从别的系统里通过WebService得到的,业务逻辑层不关心,关心的是业务逻辑层可以提供这么多数据就够了,对于客户端,只关心有这么数据我可以处理,你是从哪里得到,客户端不关心,只关心我有这么多的数据可以处理。这样,就可以实现客户端与服务器端分离开发,设计的时候更重要的是针对中间的服务和要处理的数据设计,或许就是面向契约和服务设计吧。

借用SDO的一张图。


看了这张图,我估计很多人是非常熟悉的,如果从上面的观点和角度去考虑
DTO的问题,那么这张图是自然而然的事情了,或许也是框架升级的一个必然趋势吧。这张图我是在2007年的9月份才看到的,但是时候完整的框架已经开始使用了,思想应该是相似的。

不过,这个DTO/SDO当时真的害的我很辛苦。

DTO要能够支持:数据绑定、历史记录、级联触发、合并集合、序列化与反序列化,要实现一个大的递归,从其中的任何一个对象开始,能够找出整个传递的所有数据。

1、                    数据的绑定支持。要实现IEditableObject接口,对于状态的变化要实现INotifyPropertyChanged接口,INotifyPropertyChanged接口也是微软在2.0里面新添加的,估计也是为了实现数据的双向绑定而专门添加的。实现了这两个接口,微软会自动调用的。对于容纳这些数据的集合也要支持绑定处理,则要IBindingList实现接口,这样才能够实现数据的触发,这样就要实现一个对象能够找到其所有的集合,一个集合要能够其所有的对象,这样一样,就必须实现从对象、集合、对象的递归,再深入一点,就实现了数据的级联触发,实现了双向数据触发、绑定。数据源的每个属性变更,要能够在界面上反映出来,绑定界面的改变,能够记录到后台的数据源,并且要能够支持回滚。

2、                    对于历史记录。当实现IEditableObject这个接口,则必然实现了历史记录,对于SDO来说,就是ChangeSummary。能够找到集合的所有更改的记录,包括删除的记录。对于单个对象而言是能够得到历史记录和当前数据,对于集合而言,则能够找出差异集,同时,集合也要具备集合回滚的功能。

3、                    级联触发,则是在实现数据绑定的基础上的,对于常见的主从结构,当从对象的一个属性改变了,要能够自动通知其所在的集合、集合再通知所在的对象数据改变了,如果是多层结构,则能够自动的从最底层开始一路通知到顶层。

4、                    合并集合、集合的处理。集合的处理与数据绑定是直接相当的。数据源找出差异集之后,要对差异集进行处理,处理完之后,要对原始集合进行更进一步的处理,要把两个集合进行合并处理,主要是为了同步引用。

5、                      同时,另外要实现的就是DataSDO之间的转换以及其他格式的数据与SDOData数据之间的数据转换,比如Binary/Xml/Text/Key/文件/等,最基本的是SDOData之间的转换,这些转换根据需要,有时候是单向的,有时候是双向的,根据业务需求而定。

6、                      序列化与反序列化,主要是涉及到BinaryXML序列化。对于Binary序列化,倒还是相对好处理点,对INotifyPropertyChanged的处理和ListChanged的处理要多花点心思就可以了。

Binary反序列化时有效了。

    [OnDeserialized]
        
private void OnDeserialized(StreamingContext context)
        
{
            IList
<T> list = base.Items;
            
for (int i = 0; i < list.Count; i++)
            
{
                T t 
= list[i];
                t.Attach(
this);
                SetItem(i, t);
            }

            OnListChanged(
new ListChangedEventArgs(ListChangedType.Reset, -1));
            ListChanged 
+= delegate(object sender, ListChangedEventArgs e)                 { OnDataChanged(); };
    }


在反序列化时要重建绑定,并且重新关联事件触发链。因为是不能进行序列化的,我的处理是在此时行了一个投机取巧,请朋友们能给点建议。当然,这只是针对

对于XML的序列化,遇到的问题还要大一些,因为Binary序列化,是对Field进行的,不会影响到事件的触发,也就不会影响到状态的改变,再者也不会引起递归调用了。但是对于微软提供的XML序列化,在此处的应用不能直接的用了,因为XML是对属性的处理,首先,会引起递归调用,其次,事件的触发会引起状态的改变,要对数据进行XML序列化与反序列化,则必须要打破递归调用和取消事件的触发,当然还要提供一些对于XML处理的常用函数了。通常是要实现自定义的对象图序列化反序化,在中间打断递归,对于状态的触发,则要在对象的底层加一特殊处理,阻止事件的触发。不过对于XML序列化反序列化,我还没有实现,上面的只是个思路,不一定正确。主要是因为现在的远程数据走的都是压缩的二进制,当然用的是Binary序列化,要做的是对Binary序列化进行优化。等BS结构提上日程的时候,再对这方面进行处理,会提供一组JS的函数,用于处理绑定、触发的,如果实现的话,则BS的界面也可以实现绑定处理了,只是这是后话了,至少要半年之后。

DTO方面,详细的可以参考Java阵营的SDO,再加上俺们阵营的数据绑定,综合起来,应该差不多了。

我的这个DTO/SDO的实现,已经在两个项目里面已经得到了应用,感觉是大大降低了客户端的代码量、难度、出错概率,配合代码工具,客户端的工作量是成倍的降低了。特别是出错概率,原来的项目,客户端的一个界面通常要调试很多次,而且调试过有不少地方还会出错,现在这方面已经算是非常友好了。在新的项目里面,还升级了的客户端框架,加入了变更通知,就是当关闭窗体的时候,后台判断数据是否改变,给出提示,这个功能是在客户端框架里提供的,编码的时候不会体现出来。这些在后面会慢慢的介绍的。

又写了这么多,希望大家能够共同讨论一下,给俺点建议呀

分享到:
评论

相关推荐

    简单的EntityFramework4.3+三层+DTO 简单Demo

    简单的EntityFramework4.3+三层+DTO,如果需要简化版的,我的资源里有一个不含DTO的版本。 这个Demo的主要功能是: 1、实体类的创建、复杂类型的嵌套 2、实体类的配置(主键、外键、一对一、1对多,多对多) 3、...

    Web表现层框架 MyFrame

    基本控制流程类似Struts,但业务控制类(Action)不须要实现任务接口,表单收集类也不须实现任何接口(框架中大量用到反射机制),从而不用从ActionForm拷贝属性到实体Bean直接做为DTO向下层传递。 想自己写Web框架的...

    C#.net8创建webapi,使用SqlSugar,仓储模式,DTO,服务层,控制层的综合应用

    C#.net8创建webapi,使用SqlSugar,仓储模式,DTO,服务层,控制层的综合应用。 1.付费下载后,博主保证能运行成功,不成功可以联系博主。 2.也可以私下单独联系博主进行付费下载。

    CoreWebApi通用框架.rar

    框架适用于中小项目使用。 框架包含: Swagger,JWT权限验证 ,Sqlsugar+异步泛型仓储,Redis做数据缓存,AutoFac,AOP的切面redis缓存等 仓储层: repository就是一个管理数据持久层的, 它负责数据的CRUD(Create, ...

    c#_ERP管理系统 三层架构.rar

    c#_ERP管理系统 三层架构.rar

    图书管理系统(框架)源码

    DTO为数据传输对象层,主要用来传输数据对象,MVC中Controller到View或者View到Controller的数据传输对象也放在这里面,不在使用ViewData。 Filter为拦截器层次,主要用来控制权限,操作日志的记录等。 Model为模型...

    基于Extjs的DirectCenter框架源码

    基于Extjs的DirectCenter框架源码 DirectCenter主要分为用户管理,部门管理,公司管理三个模块。 DirectCenter: DirectCenter.Model (类库项目)实体类库,其中包括hibernate映射文件(可以把映射文件放到DAL层,...

    解析ABP框架中的数据传输对象与应用服务

    展现层传入数据传输对象(DTO)调用一个应用服务方法,接着应用服务通过领域对象执行一些特定的业务逻辑并且返回DTO给展现层。这样展现层和领域层被完全分离开了。在具有良好分层的应用程序中,展现层不会直接使用领域...

    ABP开发指南

    4.3 ABP应用层—DTO有效性验证 82 4.3.1 使用数据注解 83 4.3.2 自定义检验 84 4.3.3 设置缺省值 85 4.4 ABP应用层—权限认证 86 4.4.1 定义权限 86 4.4.2 检查权限 87 4.5 ABP应用层—审计日志 90 4.5.1 配置 91 ...

    gcafeSSH:适合java初学者学习SSH的项目,可以研究其源码——SSH框架

    第一次在项目中接触DTO层:DTO通常用于不同层,降低各层之间的交换度; 表现层与应用层之间是通过数据传输对象(DTO)进行交互的,数据传输对象是没有行为的POCO对象,它的目的只是为了对领域对象进行数据封装,实现...

    医院HISDemo源码

    而不能直接走Facade层,传输的对象应该新建DTO数据传输对象,而不应该直接传递业务领域对象,从而通过SOA层我们把各个粗粒度模块完全隔离开。这个层取名为SOA也许不大恰当,大家也不必深究...计划是采用WCF 这样可以...

    一个基于SpringBoot的微服务脚手架+源代码+文档说明

    - 引入DTO层,应对前端及服务间调用 - 使用ModelMapper简化模型属性映射 - 使用PostMan+NewMan做REST接口回归测试 - 同时支持Oracle(开发/测试/生产),MySQL(本地),以及H2(内嵌) - 集成测试使用H2内存库,以避免...

    RentACar-FullStack:全栈汽车租赁项目。 实体框架核心.Net 5.0已被使用

    同样,Dto(数据访问对象)必须必须实现IDto接口。 用户,操作声明和UserOperationClaims实体已在此层上创建。 操作声明,代表基于操作的授权(角色)。 用户操作的延迟保存在UserOperationClaims中。方面验证通过...

    YoYoCms.AbpProjectTemplate:一个基于-vue + vuex + vue-router + EF开发的权限管理系统

    演示网站 首先说下这个项目吧。如标题一样是基于VUE + .NET开发...架构ABP实现了多层架构(领域层,应用层,基础设施层和表示层),以及领域驱动设计(实体,存储库,领域服务,应用程序服务,DTO等)。还实现和提供了

    SimpleTaskSystem包含NuGet

    AutoMapper(实现Dto类与实体类的双向自动转换) 客户端: Bootstrap Less AngularJs jQuery Modernizr 其他JS库: jQuery.validate、jQuery.form、jQuery.blockUI、json2 ABP框架已实现了以下特性: 多语言/本地...

    osharp.v2:osharp框架版本2.0

    数据映射:AutoMapper,主要用于数据传输对象DTO与数据实体模型Model之间的相互转化,免于繁杂的对象属性赋值 IoC组件:Autofac,定义了一个专用于处理映射的空接口IDependency,用于处理IoC接口与实现的批量映射,...

    spring-boot-rest-api-warehouse:使用Spring Boot,Maven,Hibernate,MySQL,Spring Data JPA,Flyway和Querydsl的RESTful API

    DTO DTO代表数据传输对象,我绝对选择使用DTO,以使模型层与客户端分离。 关于此主题有很多方法,但我认为最干净的方法是使用DTO仅传输所需的数据,而不是填充整个模型。 对于小型项目(如此类),DTO通常与相应

    xmljava系统源码-BJAF3.x:甲壳虫J2EE应用框架第3版,功能强大,简单易用

    xml java系统源码 BJAF3.x Beetle J2EE Application Framework Version 3,Powerful, ...NOSQL支持Redis的常用封装,支持String\Map\List\自定义DTO对象简易操作及本地内存优化及连接池优化 Service业务层 Se

    knowledge

    框架 领域模型规约 阿里规约(题主只是用VO和DO) 简写 全写 说明 DO Data Object 数据库表映射类,DAO层向上传输数据使用 DTO Data Transfer Object 数据传输对象,Service层向上传输数据使用 BO Business Object ...

    Mvc Infraestructure:J2EE的可序列化数据传输对象/通用Dao-开源

    Dto.java和其他类-用于在J2EE应用程序的业务和持久性层之间与视图(使用EL-Expression Language“层)进行数据传输。Dto从Java API的HashMap类扩展,用于通过键封装任何类型的信息类型:key_i.key_ij.key_ijk ....:...

Global site tag (gtag.js) - Google Analytics