`

谈谈我对实体的认识:DTO,DMO,DPO

阅读更多

今天和大家谈的是我对于实体的一些认识,难免有偏颇之初,还请各位指出。

 

大家都看到标题中的三个英文缩写了:DTO,DMO,DPO。DTO大家应该还是熟悉的,Data Transfer Ojbect(数据传输对象)。研究过DDD(Domain Driven Design领域驱动设计)的人应该了解过DTO。是用来传输数据的对象,应为领域对象虽然有数据(属性),但是领域对象上面还带有操作,在某些场合不适合进行传输,因为有些时候传输还需要序列化,而且也不是所有的领域对象属性都可以暴露给调用端的,而且有些属性可能要合并,可能要分解,之后才有利于调用端的使用,加上其他一些的业务原因,于是就有了专门用来传输数据的DTO,只有属性,没有操作,必要的时候加上序列化标记,实现远程调用。

 

DMO和DPO是我自己创造的名词,在后面再解释给大家听。

 

刚开始看到别人用来表达数据对象的类的时候,都是只有属性,没有操作,而且大都是和数据库表一一对应的。可以单独建立一个项目,名字叫做Project.Entity。在独立的一个项目中保存所有用到的实体,其他的项目添加对Project.Entity项目的引用。

entity1

 

就拿User举个例子吧。

public class User
{
    public Guid UserID { get; set; }

    public string Username { get; set; }
}

 

也有人喜欢在实体类添加后缀,方便标识,因为有可能领域对象也叫做User,但是觉得都叫做User又有点别扭,不好区分。就像分层的话,可能会有UserBll,UserDal之类的类产生。(在这里不讨论这些类是否合适,只是说明这种现象,但是如果大家有这方面的好思路,也可以分享一下)

 

然后不管是添加还是修改,还是查询显示,都是用这个User实体。这个在做ASP.NET或者WinForm的时候还可以。反正客户端和服务端都可以引用这个类库,不影响开发。

 

有一点,我个人比较喜欢将一些查询条件作为一个实体的属性。这样查询方法就不需要很多参数了,只有一个实体作为参数就可以了。而且在后面如果条件有变化,只要在实体添加属性,方法的内部添加或者删除参数的处理就可以了。至少调用端不用做任何修改。如果每个添加都作为一个参数的话,增加或者删除参数,服务端修改方法,调用端就需要修改调用的地方。也能减少一些开发工作吧,而且在界面的查询条件很多的时候,不至于查询方法的参数列表也很长。

例如用户查询,我就会建立一个UserFind实体。下面的例子中说明界面有两个条件,一个是用户姓名,一个是注册时间。

    public  class UserFind
    {
        public string Username { get; set; }

        public DateTime RegDate { get; set; }

        
    }

 

问题1

产生的问题就是添加的时候肯定是每个属性都要添加到数据库,修改的时候,有些属性不用或者是不能修改,允许部分的修改。还有就是显示的时候,可能还需要其他的属性,例如User实体下面可能会有一些集合属性,例如用户全部地址,邮件个数,是否有新邮件,是否有新订单之类的需求,就要在User实体添加其他属性。但是这些属性在添加和修改的时候都用不到。如果这几种情况还是共享一个实体的话,容易引起误用。而且增加沟通,需要告诉做添加功能的人,你只要添加属性1,2,3就可以了。告诉做显示的人,你需要每个属性都赋值。告诉做修改的人,属性2,3,4,5是可以修改的。

 

还有那个查询实体,例如查询订单吧。用户查询订单,只能查询自己的订单。

    public class OrderFind
    {
        public string OrderSeqNo { get; set; }

        public DateTime PlaceDate { get; set; }
    }


根据订单编号和下单时间查询。

可是后台查询用户订单的时候,可能会需要用户的信息,例如查询姓名为“张三”的订单。好吧,修改这个查询实体。

    public class OrderFind
    {
        public string OrderSeqNo { get; set; }

        public DateTime PlaceDate { get; set; }

        public string Username { get; set; }
    }

 

 

 

问题2

同样,这就需要在开发用户查询订单的时候忽略Username属性,在开发后台查询订单的时候加上Username属性。

是不是这两个功能也应该区分一下呢?

于是我就有了下面的总结。

1、实体的专用性

1) 尽量的保持实体的专用性,也就是一个功能的方法,虽然和两外一个方法的返回结果类似,可能只需要添加一两个属性,这样的情况,重新建立实体,方便后面可能对这两个方法返回内容的修改不至于相互影响。

2) 尽量保持一个实体中的每一个属性,每一个被赋值的属性,将来都会用到,否则减少实体的属性,或者新建一个实体,使用正好合适的属性个数。

3) 分离添加和显示用的实体,因为添加可能不是每个字段都需要赋值,或者一些值是默认值。

4) 分离不同类型的用户使用的实体,尽管是相同的功能。可以在类名添加ForPlanter之类的后缀来解决。因为不同用户关注的点不同,关注的属性肯定不相同。而且修改也不影响其他类型用户的使用。

最近的一个项目是WCF+Silverlight。一个类库项目不行了,需要添加两个类库项目,因为Silverlight不能添加普通类库引用,Silverlight有自己的类库项目模板。

当然了,实体的代码还是可以共享的,但是类库必须是两个。

 

在简单学习了DDD之后,发现里面的一个概念叫做DTO,数据传输对象。觉得其他和我的Project.Entity项目比较像,反正功能都是用来承载数据,不带有任何操作。甚至连数据验证都没有,数据验证可以通过attribute,集合独立的模块来完成。

 

问题2已经有了解决方案,就是保持实体的专用,减少混用。

 

可是问题1呢?

后来我们想减少代码的开发量,尤其是在增、删、改、查的数据库操作方面,想要引进一些工具类库,来帮助我们完成数据库的操作,使得我们可以专注于业务方面的开发。

这方面的类库有很多,例如:NHibernate,还有微软的Entity Framework等。引入这些时候我发现问题1变得更加突出了。要不然就会有大量的冗余字段被读取,甚至被网络传输(WCF+Silverlight的数据需要经过网络,SOAP消息的形式传输到客户端)。

 

于是DTO,DPO,DMP就产生了。

1、传输实体,经过客户端传输给wcf。在服务端可能需要组合产生新的数据库持久化实体(区分添加用实体和更新用实体),这些实体经过ORM将数据持久化到数据库。

2、从数据库查询的数据,经过ORM映射产生的实体,然后经过处理,产生传输实体,传输给客户端。

3、数据传输实体dto,数据库持久化实体dpo,数据库映射实体dmo

Technorati 标签: DTO,DPO,DMO,DDD
0
0
分享到:
评论

相关推荐

    数据库表转实体类和DTO

    数据库表转实体类和DTO是软件开发中一个常见的任务,特别是在Java后端开发中,它涉及到数据模型的设计和数据访问层的操作。实体类(Entity Class)通常代表数据库中的表,而DTO(Data Transfer Object)则用于在不同...

    laravel-dto:dto对象

    $ composer require cblink/laravel-dto -vvv 生成DTO // 默认将创建到项目app/DTO目录 php artisan make:dto BaseDTO 贡献 您可以通过以下三种方式之一进行贡献: 使用归档错误报告。 回答问题或修复上的错误。 ...

    EF+Mapper结合使用实现Dto到实体类再到数据的(框架模型基础实现)

    例如,从数据库获取用户数据并转换为DTO: ```csharp public class UserService { private readonly MyAppDbContext _dbContext; private readonly IMapper _mapper; public UserService(MyAppDbContext ...

    Dto转实体类 AutoMapper

    在软件开发中,数据传输对象(Dto,Data Transfer Object)和实体类(Entity Class)是两种常见的对象模型,它们在不同的场景中各自扮演着重要的角色。Dto主要用于在系统组件之间传递数据,而实体类通常代表数据库中...

    DTO-code-generator:DTO设计模式的代码生成

    (数据传输对象代码生成器API)可帮助开发人员快速有效地使用DTO设计模式。DTO设计模式已被广泛用于JavaEE项目中,尤其是在那些使用EJB,SOAP,REST等技术的项目中。讨厌编写DTO类并将这些值转换为Bean并反之亦然的...

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

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

    DTO设计模式.docx

    DTO(Data Transfer Object)设计模式是一种在分布式系统中广泛使用的设计模式,它的主要目的是为了在系统组件之间传递数据。在大型应用程序中,特别是在服务层和表示层之间,DTO扮演着重要角色,因为它们能有效地...

    快速生成DTO

    DTO主要用于接口调用或服务间通信,避免直接暴露数据库实体,保护数据安全。它可以减少网络传输的数据量,通过只包含必要的字段,防止过度暴露内部结构。 2. **Excel模板生成DTO**: 使用Excel模板生成DTO是一种...

    分页dto把html写在dto里

    在IT行业中,DTO(Data Transfer Object)是一种设计模式,用于在系统之间传递数据,它将业务逻辑层与表现层的数据解耦。标题“分页dto把html写在dto里”和描述“把分页按钮写在dto里,其他dto继承他”表明了一个...

    使用Java 8 Lambda表达式将实体映射到DTO的操作

    使用Java 8 Lambda表达式将实体映射到DTO的操作 在Java 8中,Lambda表达式是映射实体到DTO的一种非常有效的方法。通过使用 Lambda 表达式,我们可以将实体映射到DTO,以便更方便地进行数据处理和展示。在本文中,...

    WoAG-Analytics:DTO分析

    DTO Analytics功能 此存储库包含“整个澳大利亚政府分析”功能中使用的代码。

    java DTO 详解

    ### Java DTO 详解 #### 一、什么是DTO 在分布式系统的设计中,DTO(Data Transfer Object,数据传输对象)是一种非常重要的概念和技术手段。当客户端需要与服务器端进行交互时,尤其是在涉及大量的数据交换场景下...

    Java利用Freemarker模板自动生成dto、dao、rowmapper、bo、service代码

    本主题涉及的核心技术是使用Freemarker模板引擎来生成DTO(Data Transfer Object)、DAO(Data Access Object)、RowMapper、BO(Business Object)和服务层代码。这些组件在Spring框架中扮演着重要角色。 1. **...

    Javabean与DTO的区别.docx

    ### Javabean与DTO的区别 #### 一、JavaBean简介 JavaBean 是由 Sun 公司提出的一种标准组件模型,旨在提供一种可重用、跨平台的组件解决方案。JavaBean 的主要目的是使得 Java 类能够封装状态(属性)和行为...

    java_dao_dto生成器

    Java DAO(Data Access Object)是一种设计模式,用于封装对数据库的操作,从而将业务逻辑与数据访问逻辑分离。这种模式在大型项目中广泛应用,因为它提高了代码的可维护性和可测试性。DAO模式通常包括三个主要部分...

    DTO代码自动生成器

    DTO(Data Transfer Object)代码自动生成器是一种工具,旨在帮助开发者快速、高效地根据数据库模型创建对应的Java实体类。在软件开发过程中,DTO通常用于在系统不同层之间传递数据,避免了直接暴露业务对象,降低了...

    java-dto-mapping:Java的通用DTO映射

    您需要以某种方式将所有属性从基本实体映射到DTO实体,反之亦然,如果您无需手动映射属性即可自动执行此操作,那将是很好的选择。 这是我们可以使用ModelMapping实现的方法... 项目结构。 用户模型 在这里,我们有...

    导入Excel快速生成DTO

    在IT行业中,尤其是在Java开发领域,数据传输对象(DTO,Data Transfer Object)是一种常见的设计模式,用于在系统组件之间传递数据。"导入Excel快速生成DTO"这个标题暗示了一个工具或库,它能帮助开发者从Excel文件...

    登陆的dto.zip

    DTO,全称Data Transfer Object,是软件设计模式中的一种,主要用在分布式系统或Web服务之间,用于数据的传输。DTO对象通常不包含任何业务逻辑,仅仅是数据的载体,使得不同层之间的数据交换变得简单。在这个"登陆的...

    DTOGenerator:从类生成 DTO 的 IntelliJIDEA 插件

    generate 还将创建一个 convertFromEntity 方法,该方法会将您的实体对象中的所有值复制到 dto 中。 如果带有 DTO 后缀的类已经存在,插件将退出并且不做任何事情。 (未来版本将让用户选择目的地) 尚未实施

Global site tag (gtag.js) - Google Analytics