引言
本文中将向大家介绍我对于是使用实体的一些体验,欢迎大家拍砖。更欢迎提出不同或者相同的意见。
正文
刚开始学会使用实体的时候就是建立一个Entity类库,然后里面的实体被其他各层引用。大家传递和使用的都是这一个类库中的实体,包括前端和后台的项目都是引用这个类库,传递和操作这个类库中的实体。
就像上面的这幅图一样。每个都要添加对Entity的引用。每个项目都是这么做的,也没有发现什么不好的地方。
以前都是做一些小项目,或者是自己Demo一下。上面的做法也没有什么问题,而且看到别人的文章也都是类似这样的结构。后来在学习DDD(Domain Driven Design)的时候,看到了很多的概念。有DTO,VO,PO,BO,DAO,才发现怎么需要这么多的实体类库(有的不是类库,例如DAO)呢?觉得不可思议,这么多维护起来不是很麻烦吗?一下子还没有想到分开这么多类库的好处。
从今年年初开始接触一个大项目,到目前为止才搞完一半。主要的结构也是BLL,DAL,由于前端采用了纯Silverlight展示,所以访问数据库必须要借助服务类的项目(开始的时候我们还是用silverlight3,后来silverlight4可以使用tcp了,但是端口有限制,不适宜在互联网环境使用,容易被防火墙阻断,内网应用可以使用tcp),例如:webservice,wcf,最终我们使用的是WCF。我主要负责后台代码的编写,由于人少,后台我全负责了,包括dal,bll,wcf,一个人搞定。
wcf和silverlight之间传递数据使用强类型的实体和实体集合,但是silverlight不能添加普通类库的应用,它有自己的silverlight类库项目。当然了,silverlight也可以不添加类库,在添加服务引用的时候,会自动在silverlight项目生成wcf所需要的实体,在reference.cs文件(这个文件就是wcf在客户端的代理类,里面包括了服务的定义,也就是下图中红框框中的文件,想看这个文件,需要点击Solution Explorer的Show All Files按钮,就是解决方案管理器的左上角)中有。
于是我就建立了两个项目,一个是普通的类库,给后台的BAL,DAL,SERVICE引用;一个是silverlight的类库,给silverlight引用,他们的文件内容是一样的。当然了,需要在类和属性上添加序列化attribute。类上添加DataContract,属相上添加DataMember。
时间长了,在数据访问层就会有类似很多下面的代码。
<!--splaynam-->public List<Person> GetAll()
{
List<Person> list = null;
using (IDbConnection conn = new System.Data.SqlClient.SqlConnection())
{
conn.Open();
IDbCommand comm = conn.CreateCommand();
comm.CommandText = "select id,name from person";
IDataReader reader = comm.ExecuteReader(CommandBehavior.CloseConnection);
list = new List<Person>();
while (reader.Read())
{
list.Add(new Person()
{
ID = (Guid)reader["ID"],
Name = reader["Name"].ToString()
});
}
}
return list;
}
就想着能否简化一些呢?因为每次查询都要写while。。。reader[“”],好像都很重复,想要少些一些这样的代码。就想到了好像有ORM这种工具可以帮助实现映射和持久化,找了几个,NH,微软的EF。发现学习起来不是很顺利,以前没有项目使用过,对于他们的内部不是很了解,抛出的一些异常也不是很好解决,如果这时候引入项目的话,肯定有风险,搞不好还会拖慢进度,决定放弃引入这些ORM工具,等待详细学习了解之后再做决定。
但是上面的代码还是要简化啊,至少在从数据库的reader到entity这一层面可以想办法简化赋值过程。想到了反射,利用反射给每个属性赋值,再加上attribute,给属性打上标记,方便属性和数据库查询结果列的对应。于是就写了一个EntityMapper的小工具,来辅助实现reader到enttiy和entitycolleciton的映射。详见:利用attribute实现简单的ORM
实际上没有ORM那么强大,就是一个reader到enttiy和entitycolleciton的映射的工具,以后想着要基于这个逐步完善成一个自己的ORM,这是后话了,暂且不提。
这时候发现减少了很多的工作量,而且代码也简单多了,没有了大量的reader[“”]到属性的赋值。
我们系统的业务是经常变化的,后期有添加的需求,有修改前期的需求。导致了,实体类库需要修改,增加属性,减少属性之类的。减少还好办,顶多就是数据库查询的多了,没有属性和它对应了,我不赋值就是了。增加属性就暴露了各层公用一个实体类库的问题,还是一个不小的问题。
例如我在一个类添加一个属性,由于reader到entity的映射是采用我写的这个工具,于是添加属性,添加attribute。新方法,新存储过程,测试,没有问题。但是,这个实体的其他方法就报错了,因为其他方法对应的存储过程没有查询新添加的字段,但是在映射的时候是根据属性映射的,就报错“没有找到新属性对应的列”。好吧,那就打开老方法的存储过程,添加对于新属性的查询。问题就出来了,本来是添加方法,却还要修改以前的存储过程,少的还好,多的情况的话,就需要修改大量的存储过程,我碰到最多的一个是牵连了10个存储过程。这也可以归结为紧耦合,依赖太强了,需要解耦。
当然,改也是copy,因为字段一样,但是这个问题应该有更好的办法,这样下去,维护量会越来越大。
于是想起学习DDD的过程中遇到的那些概念了,什么BO,PO,DAO,DTO,VO的。首先给大家说一下这些概念,然后讲解我对他们的使用方案。这些概念好像在Java中非常流行,使用java进行开发的人应该更加熟悉他们。
BO:Business Object,业务对象。主要是承载业务数据的实体。处理业务逻辑的时候使用,数据结构也是针对业务逻辑建立的。
PO:persistence Object,持久化对象。数据最终要存储,无论以何种形式存储,都必须要持久化。加入使用关系数据库存储,一个PO对应一条数据库的记录,或者是对象从数据库查询出来的结果集的一条记录。
DAO:Data Access Object,数据访问对象。包含一些数据库的基本操作,CRUD,和数据库打交道。负责将PO持久化到数据库,也负责将从数据库查询的结果集映射为PO。
DTO:Data Transfer Object,数据传输对象。一般用来在前段和后台的数据传输,数据结构的简历是基于网络传输的,减少传输的数据量,避免传输过多无用的数据。
VO:Value Object,值对象。主要用在前段数据和控件的绑定操作中,以键值对的形式存在。可以从DTO转化而来,这么做的好处就是减少对于DTO的依赖,进一步减少对应后端的依赖。还可以增加前段的可测试性,也就是没有DTO,也可以对前段逻辑进行自动化的单元测试,可以通过MockDTO来达到测试的目的。
我想通过上面的这幅图来表达我的想法。web,winform,silverlight,console代表不同的前端类型。Domain代表领域对象,也可以是BLL。
获取数据的过程:首先DAO从数据库获取结果集,转换为PO。Domain接受到DAO传递过来的PO之后,负责将PO转换为BO,再进行业务逻辑的处理。处理完毕,传递BO给service,service负责转换为DTO,传输给前端接收到DTO之后,首先转换为VO,然后再进行前端的业务处理。
提交数据的过程:前端将数据整理为DTO,传输给service,service转换为BO传输给Domain,Domain转换为PO,调用DAO提供的数据持久化方法,持久化PO,DAO负责将PO持久化为数据库的数据。
好像还有一个概念叫做:POJO,这是java中的概念。POCO是.NET的概念。个人理解好像就是一类实体的统称,指的是实体没有操作,只要属性,简单实体,没有继承或者实现任何抽象的实体。凡是满足这个标准的实体都可以叫做POCO或者POJO。
分享到:
相关推荐
Java中 PO VO BO DTO DAO 和 POJO 关系图
### Java中的PO、VO、TO、BO、DAO与POJO详解 #### 一、概述 在Java企业级应用开发中,经常会遇到各种类型的对象,如PO、VO、TO、BO、DAO以及POJO等。这些对象各有侧重,在系统架构的不同层次扮演着不同的角色。...
本文将详细解析"PO/POJO/VO/BO/DAO/DTO"这六个概念,并探讨它们在实际项目开发中的作用和应用场景。 1. PO(Persistent Object,持久化对象) PO是指与数据库表结构一一对应的Java对象,它通常包含了数据库表中的...
本人以前搞不懂这些o的区别,特意查找资料总结了一下,希望也可以帮到其他人
本文将详细介绍VO (View Object)、DTO (Data Transfer Object)、BO (Business Object)、ORM (Object Relational Mapping)、DAO (Data Access Object)、Entity (实体)、DO (Data Object)、PO (Persistent Object)、...
Java 中 PO、VO、BO、POJO、DAO、DTO、TO、QO、Bean、conn 的理解 PO(Persistent Object):持久对象,指的是在 O/R Mapping 中将对象与关系数据库绑定的对象。PO 是由一组属性和属性的 get 和 set 方法组成。它...
本篇文章将对Java中的PO、VO、TO、BO、DAO、POJO等概念进行详细的解释,帮助读者更好地理解和应用这些技术。 PO(Persistant Object)持久对象 PO是Java中的一种重要概念,表示持久对象。在O/R映射中,PO通常对应...
总结来说,PO-VO-DAO-BO-POJO这些概念在Java开发中非常常见,每种类型的对象都有其特定的作用和应用场景。理解这些概念有助于更好地设计系统架构,提高代码的可维护性和扩展性。在实际开发过程中,根据项目的具体...
BO则是业务逻辑处理对象,我的理解是它装满了业务逻辑的处理,在业务逻辑复杂的应用中有用。 VO:value object值对象、view object视图对象 PO:持久对象 QO:查询对象 DAO:数据访问对象——同时还有DAO模式 DTO:...
Nginx配置文件详解Linux 安装JenkinsJAVA 多线程详解java 多线程学习How to create a Hello World with IntelliJ and Aspect JJava各种对象(PO,BO,VO,DTO,POJO,DAO,Entity,JavaBean,JavaBeans)的区分Java finally...
common-dto:数据交互层(VO、PO、BO、DTO等) service-user:用户服务提供者(用户注册、登录、权限等) operation-system:运营系统(服务消费者) 集成技术 spring spring mvc spring boot spring boot actuator...
#### 五、PO/VO/DAO/BO/DTO的区分 - **PO (Persistant Object)**:持久化对象,用来表示数据库表中的记录,每个PO对象对应一条数据库记录。 - **VO (Value Object)**:值对象,用于业务逻辑层中的数据传递。VO更多...
2. 类名遵循UpperCamelCase风格,但有一些例外,如DO、BO、DTO、VO、AO、PO、UID等,这些通常用于特定的领域模型或数据传输对象,不需严格遵循此规则。 3. 方法名、参数名、成员变量和局部变量都应使用...
除此之外,书中还涉及了如何自定义MyEclipse的编译目录,设置JAVA环境变量,以及PO、BO、VO、DTO、POJO、DAO的概念和它们在软件开发中的角色,这些都是Java开发中不可或缺的基础知识。 整体来看,这本书涵盖了从...
DTO Data Transfer Object 数据传输对象,Service层向上传输数据使用 BO Business Object 业务对象,Service输出的封装业务逻辑对象 AO Application Object 应用对象,Web层和Service层之间抽象的复用对象 VO View ...
- **类名规范**: 类名应遵循`UpperCamelCase`风格,但特定类型如DO(Data Object)、BO(Business Object)、DTO(Data Transfer Object)、VO(View Object)、AO(Application Object)、PO(Persistence Object)...
5. **PO(Plain Old Java Object)、DTO(Data Transfer Object)、BO(Business Object)、VO(Value Object)**:这些是面向对象设计中的特定类类型,用于不同层次之间的数据交换和处理: - PO:普通的Java对象,...
- **强制规定**:类名使用UpperCamelCase风格,除了以下几种特殊情况:DO(Data Object)、BO(Business Object)、DTO(Data Transfer Object)、VO(View Object)、AO(Application Object)、PO(Persistence ...