先声明一下,因为书中所举例子都是简短了代码,一步一步的,并不是一呵而成的,所以大家不要着急。
分析业务领域
软件开发的工作从问题领域的分析开始(假设没有已经存在的遗留代码或者遗留数据库)。在这个阶段,你在问题领域专家的帮助下,辨别与软件系统有关的主要实体。实体通常是为系统用户所理解的概念:付款、客户、货品、出价等。
领域模型分析和设计的目标是,为应用程序捕捉业务信息的本质。开发人员和架构师们可能不是从面向对象的模型开始,而是从一个数据模型开始应用程序设计(可能用一个实体关系图表达)。我们通常说,关于持久化,在这两者之间稍有不同;它们不过是不同的起点。最终,我们最关注业务实体的结构和关系。
CaveatEmptor领域模型
CaveatEmptor网站拍卖许多不同种类的货品,从电子设备到机票,应有尽有。拍卖根据英国的拍卖策略进行:用户连接在一件货品上出价,直到那件货品的出价期终止,最高的出价者胜出。在任何商店中,货物都是按照类别分类,并把类似的货物集中到一个分区或者架子上。拍卖目录需要某种货品类别的层次,以便买家能够浏览这些类别或者按类别和货品属性任意搜索。货品清单显示在目录浏览器中,并搜索结果屏幕。从清单中选择一件货品,把买家带到一个货品细节的视图中。
一次拍卖由一连串的出价组成,但只有一个胜出。用户细节包括姓名、注册ID、地址、电子邮件地址和帐单信息。
信任网(Web of Trust)是一个在线拍卖网站的基本特征。信任网允许用户对可信度(或者不可信度)建立信誉。买家可以对卖家进行评价(卖家也可以对买家进行评价),并且所有其他用户都可以看见评价。
领域模型的高级概览如图:
实现领域模型
在Java中实现领域模型时,必须处理几个典型的问题。例如,如何把业务关注点与横切关注点(例如事务和持久化)分开?你需要自动的还是透明的持久化?必须使用一个特定的编程模型来实现这一点吗?我们从任何实现都必须处理的一个问题开始:关注点的分离。领域模型实现通常是一个中心的组织组件;每当实现新的应用程序功能时,都要大量重用它。基于这个原因,你应该准备想尽办法确保除了业务方面的关注点之外,其余都不要渗透进领域模型实现。
处理关注点渗漏
领域模型实现是如何重要的一块代码,它不应该依赖于正交的Java API。例如,领域模型中的代码不应该执行JNDI查找或者通过JDBC API调用数据库。这事实上允许你在任何地方重用领域模型实现。最重要的是,它使得对领域模型进行单元测试变得容易,而不需要特定的运行时环境或者容器。假设领域模型应该只注重给业务领域建模。但是还有其他的关注点,例如持久化、事务管理和授权。你不应该把处理这些横切关注点的代码放在实现领域模型的那些类中。当这些关注点开始出现在领域模型类中时,就是一个关注点渗透的例子。
EJB标准解决了渗透关注点的问题。如果用实体编程模型实现领域类,容器就会替你顾及一些关注点。EJB容器利用拦截(interception)防止某些横切关注点的渗透。EJB是一个托管的组件,在EJB容器内部执行;容器拦截对bean的调用,并执行它自己的功能。这种方法允许容器以一种普通的方式实现预设的横切关注点——安全性、并发性、持久化、事务和远程。
Hibernate不是一个应用程序服务器,它不会试图实现全部EJB规范的所有横切关注点。Hibernate是只针对持久化这个关注点的一种解决方案。如果你需要声明安全性和事务管理,应该通过会话bean访问实体实例,利用这些关注点的EJB容器实现。EJB容器中的Hibernate取代了(EJB2.1,使用CMP的实体bean)或者实现了(EJB3.0,Java Persistence实体)持久化方面。
Hibernate持久化类和EJB3.0实体编程模型提供透明的持久化。Hibernate和Java Persistence还提供自动的持久化。
透明和自动持久化
我们使用透明(transparent)一词,意味着领域模型的持久化类和持久化逻辑之间一个完整的关注点分离,在这里持久化类不知道且不依赖于持久化机制。我们使用自动(automatic)一词,是指让你不用处理低级机械化细节的一种持久化解决方案,例如编写大部分SQL语句和利用JDBC API工作。此外:
1)Hibernate不需要任何特殊的超类或者接口被持久化类继承或者实现。也没有任何特殊的类被用来实现属性或者关联。
2)持久化类可以在持久化上下文之外被重用,例如在单元测试或者在用户界面(UI)层中。
3)在一个包含透明持久化的系统中,持久化关注点被具体化到一个普通的持久化管理器接口——在Hibernate中,是Session和Query。在JPA中,EntityManager和Query(有相同的名称,但是有着不同的包,以及略微不同的API)起着同样的作用。
透明的持久化产生了一定程序的可移植性;不用特殊的接口,持久化类从任何特定的持久化解决方案中分离出来。我们的业务逻辑在任何其他的应用程序上下文中都是可以重用的。可以轻松地切换到另一种透明的持久化机制。
我们认为透明是必需的。透明的持久化应该成为任何ORM解决方案的主要目标。然而,没有任何自动的持久化解决方案是完全透明的:每个自动的持久层(包括Hibernate)都在持久化类上强加了一些要求。例如,Hibernate要求把集合值(collection-values)属性定义为接口(如java.util.Set或者java.util.List),而不是定义为如java.util.HashSet这样的实际实现。或者JPA实体类必须有一个特殊的属性,称作数据库标识符。
UML图下载链接UML图