<ddd--领域驱动设计学习>讨论--------仓储

<ddd--领域驱动设计学习>讨论--------仓储

仓储委托合适的基础结构来完成自己的工作,把存储,检索,查询封装起来还是仓储的实现的最基本的特性。


还有看到网上的一句话:
“可以理解Repository就是对Dao的封装,不同点在于Repository只返回model或者model的集合,而dao则可以返回的更多比如返回一些统计数据。”

---------是不是还可以说:仓储跟dao的不同是因为仓储还包括一些业务的逻辑。

老马的一段话:
“A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes.
Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers.”


----------acting like an in-memory domain object collection.
象一个在内存里的领域对象一样运作着。仓储 就像 内存管理器一样,应该是缓存吧。 可以存放对象,删除对象。是不是可以理解:仓储具有操作对象(CRUD)功能的缓存呢?


各位老师能不能说一下 仓储怎么存放对象?是存到DB里面吗

[该贴被spring7777777于2008-12-11 21:27修改过]
[该贴被spring7777777于2008-12-11 21:30修改过]


在我的理解里面Repository和DAO没有本质的区别,以JCR为例它增加的是维护“数据集”间的关系。

Repository的最大的好处是让终端编程者彻底抛开了对于数据存储部分的理解,在这一点上和DAO目的是相通的。至于DAO提供的统计功能,那些目前主要是调用现有数据库的功能。

在现有系统的基础上我觉得层次关系可能会是:
DB <-- Repository <-- ORM
Repository是介于ORM和关系化数据存储之间的层。它本身并没有涉及到对象的层次还是面向数据的操作。

另外Repository的存储部分其实是多样化的,可以利用现有的关系数据库也可以使用XML文件等等,不是一定的。

仓储可以拥有规格检查,或许有人说也可以把规则放进dao里,但那样在变更规则组合的时候,同时也在参考数据访问的那部分代码,dao的本意就是数据访问,没有业务逻辑,有hibernate这种或类似的东西,DAO就很弱了,几乎看不到,hibernate的能力同时也拿到了对象的导航,但是它无法知道业务规格,hibernate拿到订单A了,这里有俩商品p1和p2,但是p2没货了,现在怎么处理hibernate并不知道,这需要撰写业务规格来处理:


class Repository{
Spec spec1;
public Order reload(String id){
Order order=orderdao.findById(id);
for(Product p:order.getProducts()){
spec1.check(p);
}
return order;
}
}
class Spec{
void check(Product p){
if(productdao.count(p.getName(),p.getType())<1){
//货不足的时候怎么处理,是掷出异常还是继续处理订单都只有业务才知道
throw new NoEnoughProductsException(
"没货了");
}
}
}

上面的dao就只管查询和统计,没有业务规则,就算货不足它也能安全地返回一个Order,但是实际上这个Order只是技术安全的,是业务不安全的,repository要保证这个对象也是业务安全的。

感谢 IceQi 的讨论

to freebox :

讲解的太经典了!喜欢freebox 的例子,每次都是很易接受。


仓库可以起到对领域模型的缓存以及保证领域模型的不变量,至于缓存如何实现可以参考jivedon3.0的做法,思想都差不多,通过Decerator或者proxy来进行。

好的,就要结合jdon框架学了呵呵


LZ你这里说的Repository是设计模式,还是JCR那样的标准?这2个是不同的东西了。

freebox说的和我说的不是一个东西。

to IceQi :
讨论的是:
<ddd--领域驱动设计学习>讨论--------仓储

英文名也叫 Repository ,可能是我表达不清楚,以至把你引导到 jcr的标准了,不好意思啊


呵呵,我跑题了。

那这么说起来,我觉得仓储最重要的是负担起了管理的职责,他所管理的正是业务过程中所需要的实例。

这样看起来DAO是仓储的工作基础,仓储所做的还是我们系统中描述的业务过程。他们是2个层级的关系。

谢谢大家

下面小结一下:(欢迎指错,补充)

小结:

仓储的职责:

1.担负着管理的职责,他所管理的正是业务过程中所需要的实体(或者是聚合的根)

2.仓储所做的还要包括我们系统中描述的业务过程,repository要保证处理对象是业务安全的。


仓储的作用:

仓储可以起到对领域模型的缓存功能 以及 保证领域模型的不变量

仓储与dao的区别,联系:

1.dao是仓储的基础(但是用到 orm 的时候dao会很弱,dao的功能就会转移到了 ibatis 和hibernate上了)

2.dao不知道业务。仓储知道,并且负责业务逻辑。

Repository具有业务意义,它包含了业务逻辑(应用逻辑),像freebox例子中的spec。
[该贴被smokemice于2009-01-12 15:16修改过]


-----------补充---------------------banq以前的总结:

>这个意思是不是DAO可以使用DAO缓存代理来提高性能,而Repository不可以直接使用缓存

我认为对象缓存放在DAO中不合适,而是在Repository中,Repository=对象工厂+对象缓存+DAO 是这样一个组成。

DAO只是动作纯粹的动作,分为读、写2种,不涉及任何业务过程。

只有缓冲才能够提高性能。

只有业务过程才能够提供缓冲。

Repository正是提供这样的业务过程。

不知所云,freebox 的那个例子 有问题,在重建订单的过程中 不会出现p1或者p2 不存在的问题,如果出现也可能是一个设计时考虑的权衡,比如历史订单中的商品已经下线了,这是可以采用数据冗余来解决这样的问题