《POJOs in Action》的原文摘录

  • 表示层或facade首先调用PlaceOrderService更新PendingOrder,然后调用RestaurantRepository获取可选餐馆,PlaceOrderService并不返回可选餐馆的列表,如果它这么做了,就会和UI设计仅仅耦合在一起。最好让服务和UI分离,让领域模型的客户再次调用领域模型以取得它要显示的数据。facade或表示层调用领域模型服务更新领域模型,并调用仓库取得显示给用户的数据。领域模型被本地调用给调用,因此多次调用并无太大开销,这一点非常重要。 (查看原文)
    stephansun 2013-03-31 10:32:33
    —— 引自第74页
  • 访问仓库的各种选择 仓库主要由领域服务使用,不过它们也被一些实体如PendingOrder调用。要对仓库对象调用方法,调用者必须明显持有该对象的引用。此前你已看到仓库如何作为构造函数参数传入PlaceOrderSerivce。然而,就下面我要描述的理由来看,对领域模型实体,并不总能做到这一点。下面,我们来探究一下这个问题及其各种解决方法。 最便利的方案是将仓库作为构造函数参数传入实体,和它们传入服务的方式一样。这样以来,实体就能借助轻量级容器的构造子注入机制进行初始化。与将仓库作为方法参数传递相比,将仓库作为构造函数参数传递要简单得多,而且不存在使用singleton时的缺点,我稍后再作描述。然而,使用这种方案初始化实体并不那么直接,因为它与服务不同,服务一般由轻量级容器实例化,而实体则是在数据库加载时,由持久层框架创建的。 默认情况下,持久层框架使用类的默认构造函数直接创建对象,因此不可能传入任意必须的对象。有些(并非所有)持久层框架具备可配置的对象实例化机制,允许应用程序控制对象如何实例化。应用程序可以配置持久层框架,请参看http://hibernate.org/182.html[Hibernate注入]。不过,由于该方案不是到处都有,因此我们不打算在本书中使用这种方案。 另一种选择是使用静态方法和变量实现仓库。例如,你可以singleton或ThreadLocal实现仓库。这种方案对所有持久层框架都有效,而且不要求仓库到处传递,有时,代码可能因此过于复杂。静态方法和变量存在的问题是它们使代码更难测试。例如,它们会阻止你使用替代实现比如模拟对象,因为你无法把静态方法或变量的访问重定向至另一个类。由于代码依赖必须初始化的静态变量,因此它们还引入了隐藏的依赖。总之,最好避免静态方法和变量。 由于只有某些持久层框架允许你使用构造子注入初始化实体,而使用静态方法和变量又存在一... (查看原文)
    stephansun 2013-03-31 10:43:07
    —— 引自第88页
  • ORM的限制 另外,你也许设计了一个领域模型,无法映射到合乎要求的数据库模式。如果真的碰到这种情况,你久必须修改领域模型和数据库模式两者之一...但是,一旦修改了数据库模式,那我就需要相应地更改领域模型。 (查看原文)
    stephansun 2013-03-31 11:01:07
    —— 引自第116页
  • 另一个主要区别是POJO facade向表示层返回领域对象而不返回DTO。例如,稍后你将看到,实现“下订单”用例的POJO facade会返回PendingOrder领域对象,而不返回包含其数据拷贝的DTO。由于你不必为每个领域对象定义DTO和编写构造DTO的代码,在某些应用程序里,这部分代码可能多达10%,因此可以显著简化整个facade。 (查看原文)
    stephansun 2013-03-31 11:07:39
    —— 引自第245页
  • 这些类按如下方式阻止在一起。当表示层调用PlaceOrderFacade时,Spring TransactionInterceptor便开始一项事务,并打开一个持久层框架连接,供仓库使用。PlaceOrderFacadeImpl则调用领域模型类验证输入并执行计算。当PlaceOrderFacade返回时,TransactionInterceptor关闭持久层框架连接并提交该事务。 (查看原文)
    stephansun 2013-03-31 11:11:08
    —— 引自第247页
  • Transaction Script模式... 所以,这种模式只应该在这样的情况下应用:应用程序的业务逻辑及其简单,或者持久层框架访问数据库的效率不够高时。 (查看原文)
    stephansun 2013-03-31 11:23:09
    —— 引自第359页