Java数据模型设计探讨和交流
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
HTML Tag JavaScript Object/Array/…
Java系统中的数据模型
HashMap ---由DataSet提供 JavaBean ---由SQL Map提供 DomainObject ---由O/R Map提供
数据库的数据模型
Table record
数据模型的转换方式
Java Object HTML Tag
混合使用Hibernate和JDBC TempLeabharlann Baiduate的示范
public void updateUser(User user) { user.setName("robbin"); getHibernateTemplate().save(user); getHibernateTemplate().flush(); // 同步Hibernate一级缓存 jdbcTemplate.update("update book set name = 'spring'"); getHibernateTemplate().clear(); // 清除Hibernate一级缓存 getSessionFactory().evict(Book.class); // 清除Hibernate二级缓存 }
ActionForm OGNL(最直接的转换方式) JSTL EL(只有单向转换)
Java Object Java Object
O/R Map SQL Map DataSet
JavaScript Object Table record
AJAX分布式调用框架(DWR,Bufflo)
Java中采用何种数据模型的依据
public class Department { public List<Employee> getEmployees() { return employees; } public void setEmployees(List<Employee> employees) { this.employees = employees;} public addEmployee(Employee employee) { employees.add(employee); } public fireEmployee(Employee employee) { employees.remove(employee); } } public class DepartmentDao { public fireEmployee(Employee employee) { department.fireEmployee(employee);
相比失血模型,OO结构有所改善 领域模型带有领域逻辑,提供了可重用性,简 化了业务逻辑层的职责 各层单向依赖,领域模型稳定,实现起来也很 容易
缺点
领域逻辑和业务逻辑划分应该根据业务需求分 析,而不是根据持久化与否
充血模型
所有领域逻辑都封装到领域模型中,不管是 否涉及持久化 业务逻辑层只提供一层很薄的封装,不涉及 过多的逻辑处理,主要作用是用来提供事务 封装和安全性检查
失血模型优点和缺点
优点
层次结构清楚,各层单向依赖 比较容易学习和掌握,在设计的时候不会产生歧义 DomainModel因为只包含映射到数据库的信息,所以相 当稳定
缺点
严重违背OO原则:对象的行为应该和它的状态封装在一 起 造成业务逻辑层的TransactionScript膨胀,难以维护和 重用
贫血模型
HashMap JavaBean DomainModel
Table Record
Employee
Name 张三 李四
Department
Age 20 24 男 男
Gender
Department _id 1 2
Id 1 2
name 开发部 财务部
Hash Map
Map1.put(“name”, “张三”); Map1.put(“gender”,”男”); Map1.put(“age”, 20); Map1.put(“department_id”, 1);
采用充血模型的架构
业务逻辑层
DomainModel
DAO接口
充血模型优缺点
优点
符合OO原则,有利于面向对象设计的实现 领域模型的可重用性高 业务逻辑层简单 针对复杂领域模型的业务比较合适
缺点
DomainModel和DAO形成双向依赖关系,是一个很不好的编程味道 DomainModel塞的东西太多,会变得非常不稳定,经常变动 业务逻辑层仍然要封装DomainModel交互的业务逻辑,那么一个业务究竟应该属 于领域逻辑,划分给DomainModel呢?还是应该属于业务逻辑,划分给业务 Bean的呢,这在实际项目中会带来设计上含混和争议 出于事务封装的考虑,业务逻辑层必须提供对所有领域逻辑的封装,这等于是在业 务逻辑层重新定义一遍领域逻辑,工作不但烦琐枯燥,而且对于外部的Web程序员 来说,和贫血模型没有任何区别,通过横切方式封装事务的、面向过程的业务逻辑 层彻底抵消了底层面向对象的领域模型带来的好处 领域逻辑实现可能有多种方式,一旦反向依赖DAO,就会造成调用DAO的时候, 必须由DAO选择返回哪种领域逻辑实现,那么领域逻辑就会和DAO藕合到一起, 违背了DAO层分离持久化逻辑的初衷
缺点
学习门槛颇高,需要良好的面向对象设计和编程的基础,也需要对关系数 据库良好的理解 需要对O/R Mapping工具良好的掌握,稍有不甚,就会出现性能问题 针对DomainModel的透明持久化远远达不到完全的透明,陷阱比较多 批量数据处理的领域和报表统计领域并不适合使用DomainModel
一个看似透明实则性能很差的例子
添加了不依赖持久化的领域逻辑 凡是依赖持久化的领域逻辑则被放入到业务 逻辑层 一个业务操作究竟是领域逻辑还是业务层逻 辑,根据是否依赖持久化进行划分(按照OO原
则,不应该由技术细节决定面向对象设计,但是从实用 角度出发,放弃一些理论的原则,根据实际的技术情况 进行折衷可能更好)
贫血模型的优缺点
优点
浏览器端的数据模型和数据库的数据模型是 给定的,我们需要根据Java系统的外部数据 模型,以及转换方式的不同来调整Java系统 中的数据模型(外在限制) 在现有的技术框架前提下,尽量以面向对象 的方式来设计Java系统中的数据模型(内在 限制)
Java系统中的数据模型
DTO(数据传输对象)
ActionForm ---用于和HTML Tag匹配的数据表 示方式,常见于Struts,Spring Web MVC DomainModelDTO ---用于和分布式调用客户端 (例如JavaScript Object)数据模型匹配
DomainModel优缺点
优点
符合OO原则,有利于面向对象设计的实现 可以利用面向对象的继承、多态、组合、关联等对象表示方式以达到最大 灵活性,最大限度的表示真实世界的事物,以及事物之间的关系 透明的持久化(只需要持久化一级对象,二级对象按照持久化可达性自动 持久化) 持久化代码自动生成,编程及其简单和高效 容易插入缓存层,以提高性能
实战的提示
在很多具有一定需求复杂度的项目中,O/R Map无法做到100% 使用DomainModel来完成所有任务,由于关系模型导致的性能 考量,在5-10%的情况下可能需要放弃DomainModel,转而采 用HashMap/JavaBean的数据模型 采用Hibernate/Spring JDBC Template的组合是一个非常棒的 解决方案,大多数情况使用Hibernate操作DomainModel,少数 情况使用JDBC Template来搞定。特别值得一提的是,你可以在 一次事务中既使用Hibernate,又使用JDBC Template, Spring会自动识别这种情况,对它们提供同一个数据库连接,将 它们加入同一事务的范围内,这时候唯一需要注意的问题就是 Hibernate的缓存同步和失效处理
SQL Map
JavaBean
Name Age Gender Departm ent_id 1 2
张三 李四
20 24
男 男
JavaBean
JavaBean方式的优点和缺点
优点
带有强类型检查 和数据库字段一一对应,可以通过数据库 Schema自动生成,和数据对应关系简单 对于熟悉数据库的人来说,易学易用,非常直观
DomainModel的探讨
失血的DomainModel 贫血的DomainModel 充血的DomainModel 胀血的DomainModel
失血模型
定义
仅仅包含了getter/setter方法的实体类 不包含任何DomainLogic
采用失血模型的应用程序架构
业务逻辑层
DAO接口
DomainModel
使集合实例化,发送一条SQL,把该部门所有的employee都查询出来了,这是不可接受的
// 隐含了对集合元素的操作,迫
选择不同的数据模型的原则
OLTP型应用考虑选择DomainModel, OLAP型应用考虑选择JavaBean 应用软件系统面向对象方式驱动设计,采用 DomainModel;面向E/R模型驱动设计, 采用JavaBean 设计和开发团队的面向对象基础比较好,采 用DomainModel,数据库编程基础好,采 用JavaBean 特殊应用考虑HashMap
HashMap的应用场合
和Web控件绑定的DataSet JDBC取出的结果集 Hibernate中的动态对象映射 复杂报表的统计运算
JavaBean方式的SQL Map
Employee.setName(“张三”); Employee.setAge(20); Employee.setGender(“男”); Employee.setDepartment(1);
Java数据模型设计的探讨
Robbin(fankai@gmail.com) http://www.javaeye.com
内容提示
软件系统中的数据模型概述 Java系统中各种数据模型介绍 领域模型的分类以及分析 领域模型与AJAX
数据模型为什么这么重要
软件本质上就是“数据”的输入、输出和处 理,如果说软件是人的身体,数据就是人体 内流动的血液 合理的数据模型是软件设计和开发成功的关 键
Hash Map
Name Age Gender Departm ent_id 1 2
张三 李四
20 24
男 男
HashMap优点和缺点
优点 数据结构可以动态调整,带来了特定需求情况下的最大编程灵活 性 对于熟悉关系数据库的人来说,容易理解和掌握(相当于在内存 中离线方式的数据库) 和某些工具配合,可以达到很高的开发效率(Microsoft dotnet DataSet) 缺点 严重违背OO原则,不利于面向对象设计的实现 缺少强类型检查,程序非常容易出错 缺少强类型检查,导致很多外部框架无法对其进行增强 太多的隐式契约,代码可读性和可维护性太差,非常容易出错 只能适用简单的关系模型,复杂的模型条件下,程序空前混乱
充血模型优缺点
从技术实现角度来说,存在一定的困难
当Item依赖ItemDao的时候,需要依靠IoC容 器注入DAO,但是item对象往往是通过O/R Map工具得到的,或者通过new方法得到的, IoC容器难以实现post-instantiation,即使实 现,效率也值得置疑。 Spring2.0通过用AspectJ增强DomainModel 实现了post-instantiation,但是带来了很强的 框架依赖性,显然得不偿失
缺点
违背OO原则,不利于面向对象设计的实现 持久化方式不透明,需要手工控制来维护关联关 系
DomainModel
Employee Department
public class Employee { private Department department; } public class Department { private List<Employee> employees = new ArrayList<Employee>; }
应用软件的体系结构
Direct HTTP
HTML Tag
Java Object Table record
Browser
AJAX JavaScript Object
Java System
DataBase
Java Object
数据的显示
数据的处理
数据的存储
各个软件中的不同数据模型
浏览器里面的数据模型
Java系统中的数据模型
HashMap ---由DataSet提供 JavaBean ---由SQL Map提供 DomainObject ---由O/R Map提供
数据库的数据模型
Table record
数据模型的转换方式
Java Object HTML Tag
混合使用Hibernate和JDBC TempLeabharlann Baiduate的示范
public void updateUser(User user) { user.setName("robbin"); getHibernateTemplate().save(user); getHibernateTemplate().flush(); // 同步Hibernate一级缓存 jdbcTemplate.update("update book set name = 'spring'"); getHibernateTemplate().clear(); // 清除Hibernate一级缓存 getSessionFactory().evict(Book.class); // 清除Hibernate二级缓存 }
ActionForm OGNL(最直接的转换方式) JSTL EL(只有单向转换)
Java Object Java Object
O/R Map SQL Map DataSet
JavaScript Object Table record
AJAX分布式调用框架(DWR,Bufflo)
Java中采用何种数据模型的依据
public class Department { public List<Employee> getEmployees() { return employees; } public void setEmployees(List<Employee> employees) { this.employees = employees;} public addEmployee(Employee employee) { employees.add(employee); } public fireEmployee(Employee employee) { employees.remove(employee); } } public class DepartmentDao { public fireEmployee(Employee employee) { department.fireEmployee(employee);
相比失血模型,OO结构有所改善 领域模型带有领域逻辑,提供了可重用性,简 化了业务逻辑层的职责 各层单向依赖,领域模型稳定,实现起来也很 容易
缺点
领域逻辑和业务逻辑划分应该根据业务需求分 析,而不是根据持久化与否
充血模型
所有领域逻辑都封装到领域模型中,不管是 否涉及持久化 业务逻辑层只提供一层很薄的封装,不涉及 过多的逻辑处理,主要作用是用来提供事务 封装和安全性检查
失血模型优点和缺点
优点
层次结构清楚,各层单向依赖 比较容易学习和掌握,在设计的时候不会产生歧义 DomainModel因为只包含映射到数据库的信息,所以相 当稳定
缺点
严重违背OO原则:对象的行为应该和它的状态封装在一 起 造成业务逻辑层的TransactionScript膨胀,难以维护和 重用
贫血模型
HashMap JavaBean DomainModel
Table Record
Employee
Name 张三 李四
Department
Age 20 24 男 男
Gender
Department _id 1 2
Id 1 2
name 开发部 财务部
Hash Map
Map1.put(“name”, “张三”); Map1.put(“gender”,”男”); Map1.put(“age”, 20); Map1.put(“department_id”, 1);
采用充血模型的架构
业务逻辑层
DomainModel
DAO接口
充血模型优缺点
优点
符合OO原则,有利于面向对象设计的实现 领域模型的可重用性高 业务逻辑层简单 针对复杂领域模型的业务比较合适
缺点
DomainModel和DAO形成双向依赖关系,是一个很不好的编程味道 DomainModel塞的东西太多,会变得非常不稳定,经常变动 业务逻辑层仍然要封装DomainModel交互的业务逻辑,那么一个业务究竟应该属 于领域逻辑,划分给DomainModel呢?还是应该属于业务逻辑,划分给业务 Bean的呢,这在实际项目中会带来设计上含混和争议 出于事务封装的考虑,业务逻辑层必须提供对所有领域逻辑的封装,这等于是在业 务逻辑层重新定义一遍领域逻辑,工作不但烦琐枯燥,而且对于外部的Web程序员 来说,和贫血模型没有任何区别,通过横切方式封装事务的、面向过程的业务逻辑 层彻底抵消了底层面向对象的领域模型带来的好处 领域逻辑实现可能有多种方式,一旦反向依赖DAO,就会造成调用DAO的时候, 必须由DAO选择返回哪种领域逻辑实现,那么领域逻辑就会和DAO藕合到一起, 违背了DAO层分离持久化逻辑的初衷
缺点
学习门槛颇高,需要良好的面向对象设计和编程的基础,也需要对关系数 据库良好的理解 需要对O/R Mapping工具良好的掌握,稍有不甚,就会出现性能问题 针对DomainModel的透明持久化远远达不到完全的透明,陷阱比较多 批量数据处理的领域和报表统计领域并不适合使用DomainModel
一个看似透明实则性能很差的例子
添加了不依赖持久化的领域逻辑 凡是依赖持久化的领域逻辑则被放入到业务 逻辑层 一个业务操作究竟是领域逻辑还是业务层逻 辑,根据是否依赖持久化进行划分(按照OO原
则,不应该由技术细节决定面向对象设计,但是从实用 角度出发,放弃一些理论的原则,根据实际的技术情况 进行折衷可能更好)
贫血模型的优缺点
优点
浏览器端的数据模型和数据库的数据模型是 给定的,我们需要根据Java系统的外部数据 模型,以及转换方式的不同来调整Java系统 中的数据模型(外在限制) 在现有的技术框架前提下,尽量以面向对象 的方式来设计Java系统中的数据模型(内在 限制)
Java系统中的数据模型
DTO(数据传输对象)
ActionForm ---用于和HTML Tag匹配的数据表 示方式,常见于Struts,Spring Web MVC DomainModelDTO ---用于和分布式调用客户端 (例如JavaScript Object)数据模型匹配
DomainModel优缺点
优点
符合OO原则,有利于面向对象设计的实现 可以利用面向对象的继承、多态、组合、关联等对象表示方式以达到最大 灵活性,最大限度的表示真实世界的事物,以及事物之间的关系 透明的持久化(只需要持久化一级对象,二级对象按照持久化可达性自动 持久化) 持久化代码自动生成,编程及其简单和高效 容易插入缓存层,以提高性能
实战的提示
在很多具有一定需求复杂度的项目中,O/R Map无法做到100% 使用DomainModel来完成所有任务,由于关系模型导致的性能 考量,在5-10%的情况下可能需要放弃DomainModel,转而采 用HashMap/JavaBean的数据模型 采用Hibernate/Spring JDBC Template的组合是一个非常棒的 解决方案,大多数情况使用Hibernate操作DomainModel,少数 情况使用JDBC Template来搞定。特别值得一提的是,你可以在 一次事务中既使用Hibernate,又使用JDBC Template, Spring会自动识别这种情况,对它们提供同一个数据库连接,将 它们加入同一事务的范围内,这时候唯一需要注意的问题就是 Hibernate的缓存同步和失效处理
SQL Map
JavaBean
Name Age Gender Departm ent_id 1 2
张三 李四
20 24
男 男
JavaBean
JavaBean方式的优点和缺点
优点
带有强类型检查 和数据库字段一一对应,可以通过数据库 Schema自动生成,和数据对应关系简单 对于熟悉数据库的人来说,易学易用,非常直观
DomainModel的探讨
失血的DomainModel 贫血的DomainModel 充血的DomainModel 胀血的DomainModel
失血模型
定义
仅仅包含了getter/setter方法的实体类 不包含任何DomainLogic
采用失血模型的应用程序架构
业务逻辑层
DAO接口
DomainModel
使集合实例化,发送一条SQL,把该部门所有的employee都查询出来了,这是不可接受的
// 隐含了对集合元素的操作,迫
选择不同的数据模型的原则
OLTP型应用考虑选择DomainModel, OLAP型应用考虑选择JavaBean 应用软件系统面向对象方式驱动设计,采用 DomainModel;面向E/R模型驱动设计, 采用JavaBean 设计和开发团队的面向对象基础比较好,采 用DomainModel,数据库编程基础好,采 用JavaBean 特殊应用考虑HashMap
HashMap的应用场合
和Web控件绑定的DataSet JDBC取出的结果集 Hibernate中的动态对象映射 复杂报表的统计运算
JavaBean方式的SQL Map
Employee.setName(“张三”); Employee.setAge(20); Employee.setGender(“男”); Employee.setDepartment(1);
Java数据模型设计的探讨
Robbin(fankai@gmail.com) http://www.javaeye.com
内容提示
软件系统中的数据模型概述 Java系统中各种数据模型介绍 领域模型的分类以及分析 领域模型与AJAX
数据模型为什么这么重要
软件本质上就是“数据”的输入、输出和处 理,如果说软件是人的身体,数据就是人体 内流动的血液 合理的数据模型是软件设计和开发成功的关 键
Hash Map
Name Age Gender Departm ent_id 1 2
张三 李四
20 24
男 男
HashMap优点和缺点
优点 数据结构可以动态调整,带来了特定需求情况下的最大编程灵活 性 对于熟悉关系数据库的人来说,容易理解和掌握(相当于在内存 中离线方式的数据库) 和某些工具配合,可以达到很高的开发效率(Microsoft dotnet DataSet) 缺点 严重违背OO原则,不利于面向对象设计的实现 缺少强类型检查,程序非常容易出错 缺少强类型检查,导致很多外部框架无法对其进行增强 太多的隐式契约,代码可读性和可维护性太差,非常容易出错 只能适用简单的关系模型,复杂的模型条件下,程序空前混乱
充血模型优缺点
从技术实现角度来说,存在一定的困难
当Item依赖ItemDao的时候,需要依靠IoC容 器注入DAO,但是item对象往往是通过O/R Map工具得到的,或者通过new方法得到的, IoC容器难以实现post-instantiation,即使实 现,效率也值得置疑。 Spring2.0通过用AspectJ增强DomainModel 实现了post-instantiation,但是带来了很强的 框架依赖性,显然得不偿失
缺点
违背OO原则,不利于面向对象设计的实现 持久化方式不透明,需要手工控制来维护关联关 系
DomainModel
Employee Department
public class Employee { private Department department; } public class Department { private List<Employee> employees = new ArrayList<Employee>; }
应用软件的体系结构
Direct HTTP
HTML Tag
Java Object Table record
Browser
AJAX JavaScript Object
Java System
DataBase
Java Object
数据的显示
数据的处理
数据的存储
各个软件中的不同数据模型
浏览器里面的数据模型