CQS问题?

一个极端的例子,添加一个对象到数据库并返回其ID,CQS如何分离?
object id = db.add(Object entity)

添加是写,返回只是写的结果,这个简单一个函数就可以实现,CQRS是复杂系统,有一堆写,有一堆读才需要。

2012-12-19 14:10 "@banq"的内容
添加是写,返回只是写的结果,这个简单一个函数就可以实现,CQRS是复杂系统,有一堆写,有一堆读才需要。 ...

这是极端的情况,
有写也有读, CQS不是说了,任何函数最终都可以分解为读操作与写操作的组合.
上面例子有写操作也有读返回,很明显不满足CQS,如何分解?

[该贴被clonalman于2012-12-19 16:42修改过]

2012-12-19 16:39 "@clonalman"的内容
有写也有读, CQS不是说了,任何函数最终都可以分解为读操作与写操作的组合.
上面例子有写操作也有读返回,很明显不满足CQS,如何分解? ...

这是90%的写和10%的读。个人觉得,合适才是最好的,不一定非要这般彻底遵循CQS,设计应该更多的是一种平衡,理论与实际情况相结合。
也有人提过Design by contract,但是大多数情况下我们只验证precondition,甚至某些情况权衡其它因素,在一些不重要的地方或基本不可能出错的地方完全不验证输入,这不见得就是错的

很简单,cqrs中 Command 也是要返回结果的,但这个结果只是提示性结果,和查询性信息还是有区别的。

这个不矛盾。

2012-12-19 16:39 "@clonalman"的内容
任何函数最终都可以分解为读操作与写操作的组合. ...

是不是能发明一种读写分离的语言,现在Java和C#中Bean的特征是getter和setter,应该将这两种方式分离到两种Bean中。

使用这种读写分离的语言编程起来就非常脉络清楚,而且对可变状态的管理能够非常精确,我现在在JiveJdon的编程中已经开始遵循这种原则,对于一个领域对象如果同时用于读写,就建立两种分别用于读和写的构造器函数,有时为了特别分清楚这种分别,特别是标识写的作用,再用一个事件实体包装它。

比如:


public class A{
...
//用于写的构造器
public A(B b){

}

//用于读的构造器
public A(C c){

}

}

一般写都是command -->事件形式,那么使用A对象作为写时,再用事件值对象包装:


public class ACreatedEventVO{
private final A a; //用final保证不变性。

public ACreatedEventVO(A a){

}
..
}


2012-12-19 09:41 "@clonalman"的内容
一个极端的例子,添加一个对象到数据库并返回其ID,CQS如何分离?
object id = db.add(Object entity) ...

CQS不里是用在这些地方的。。。。CQS是对系统而言,“用户获取信息”与“逻辑计算中获取数据”是不同的。

单从这一句分析,这是一条Command,因为它不是单纯地用户获取信息,它引起了状态变化。

2012-12-19 09:41 "@clonalman"的内容
一个极端的例子,添加一个对象到数据库并返回其ID,CQS如何分离?
object id = db.add(Object entity) ...

add本身是一个Command,不需要分离,一个Command是允许返回执行结果的

2012-12-21 17:03 "@cloudstack"的内容
add本身是一个Command,不需要分离,一个Command是允许返回执行结果的 ...

这是比较直接添加一个属性返回