1. 业务层的组织结构——组织业务逻辑
1) 使用过程式设计
i. 事务脚本(Fowler):通过过程来组织业务逻辑,其中每一个过程用来处理来自表示层的一个单独的请求。这样做使得实现行为的类和存储状态的类分开
ii. 事务脚本设计的结构:大型的事务脚本和大量的小数据对象
事务脚本 |
事务脚本 |
数据对象 |
行为 |
状态 |
2) 使用面向对象设计
i. 领域模型(对象模型):Fowler把用来开发业务逻辑的面向对象方法称为领域模型(Domain Model)。它能充分利用继承和回环调用等特性。
ii. 领域模型的结:兼具状态和行为的小型类
行为 |
状态 |
3) 数据表模块(Table Module)模式(不推荐)
比事务脚本模式更加结构化,因为对于每个数据库表,它都定义了一个数据表模块类,这个类实现操作对应数据表的代码,和事务脚本一样,它也把状态和行为分到不同的类里面。
2. 暴露给表示层及其他客户程序的接口——封装业务逻辑
1) EJB session façade
使用session façade封装业务对象,存在会话bean只能运行在ejb容器里这一不足。
2) POJO façade
是一个pojo而非ejb,事务管理和安全等服务则由aop而不是ejb容器提供。
(pojo façade无法参与由远程客户发起的分布式事务)
3) 暴露领域模型模式(Exposed domain model pattern)
表示层直接调用领域对象而不是通过façade。但是这样就增加了表示层的复杂度,因为表示层必须管理数据库连接。
注:将持久层领域对象返回给表示层的代码特别容易出错。由于表示层可能尝试访问业务层未加载的对象(在hibernate中,这是因为延迟加载的问题),因此产生运行时错误的风险也会加大。如果使用JDO,hibernate或EJB3,你可以把领域对象模型暴露给表示层,并允许业务层将持久领域模型返回给表示层,从而避免这个问题(这就是Open session in view)(这里我的理解就是在业务逻辑里面写持久层操作代码)。当表示层游历于领域对象之间的关系时,持久层框架就会加载它访问的对象,这就是所谓的延迟加载技术。
3. 持久层如何访问数据库。
1) 直接使用JDBC存在的问题
i. 开发和维护sql困难而且耗时
ii. Sql缺少可移植性
iii. 编写jdbc代码耗时而且容易出错
注:有时为了取得最佳性能,我们必须使用sql的特定功能,包括厂商提供的专有特性,这时我们就不能使用即时生成sql的持久层框架。
2) 使用ibatis
3) 使用持久层框架
Hibernate 和JDO
4. 处理数据库事务中的并发(单个数据库事务)。
1) 隔离的(isolated)数据库事务
存在性能较低的瓶颈,可以考虑使用锁机制替代。
2) 乐观锁
乐观锁的工作原理是让应用程序检测它即将更新的数据是否已被另一个事务修改。
通常是在表中增加一个版本字段。
适用于并发更新的几率极小,此外应用程序不是阻止并发更新,而是检测并发更新并回滚。
3) 悲观锁
读取某些记录时先锁定这些记录,阻止其他事务访问这些记录。具体细节由数据库决定。
5. 处理长事务中的并发(多个数据库事务)。
1) 乐观离线锁模式(optimistic Offline Lock)
用户要等待回滚,因此等待时间过长。
2) 悲观离线锁模式(Pessimistic Offline Lock)
在编辑过程开始之初,锁定共享数据(由应用程序进行锁定而不是数据库)。