CQRS讨论
今天和同事一起讨论了CQRS(Command Query Responsibility Segregation),过程中,我产生了一些疑问,先记录在这里,以后有解决方案了再说。:)
http://blog.jteam.nl/2009/12/21/rethinking-architecture-with-cqrs/
以下是讨论正文:
发件人: 1B-2-12 胡庆访;
发送时间: 2009年12月31日 12:36
收件人: 1B-2-14 穆洪星;3D-1-02 周金根
抄送: 1B-2-05 李智; 1B-2-13 孟伟斯
主题: 答复: 使用CQRS重新考虑架构
CQRS其实是说在使用DDD的应用程序中,可以把查询分开来,这样可以提高查询的效率。不知道我这样理解对不对。
不过这点我之前做程序的时候也有所体会。Web开发使用纯粹的DDD,还要保证不错的效率,是一个挑战!类似这个问题,在我的这篇博客中有写。
我之前分享给大家的那个网站591jzw,就是朝着这个方向前进的。
其底层使用了LINQ TO SQL作为一般的Class-Table级映射,提高数据访问的高开发效率。(如果觉得某个方法的性能较低,可以直接使用优化过的查询替换LINQ To SQL 即可。)然后再经过组合而成的中间层领域模型,针对的就是复杂的业务逻辑。
当时,为了不让查询分离而能使用模型取出指定的,我使用的模式是:在方法名中指定所需要的信息。这是考虑过很久后才决定使用的。不过的确是很丑!目前也没想到什么好办法,嘿嘿。
不过后来觉察到,就算这样,还是不应该所有的情况都使用Model来查询数据。类似纯报表的场景下,直接使用SQL当然最好了。这可能就是所谓的CQRS吧。
但是,如果这样,我也有个比较大的问题:有些数据是经过业务逻辑计算出来的,如果把它的查询放在SQL中,我觉得实在是有太舒服。这点有没有什么好的办法呢?
另外,关于贫血模式,如同文中作者所说,离DDD太远了……纯粹的数据,又怎么能叫OO呢?
至于是用Struct还是 用Class,我觉得这个也是一种权衡吧。虽然C#中也可以使用Struct进行数据定义,并在栈上分配,速度较快。不过Struct是不能实现OO的,这个就得考虑模型使用的上下文了。
题外话:
如果使用Struct来实现贫血模型的时候,Struct的性质注定了它要不停的Copy值,我感觉也会造成比较大的开销,不知道对不对?
发件人: 1B-2-14 穆洪星
发送时间: 2009年12月31日 9:36
收件人: 3D-1-02 周金根
抄送: 1B-2-05 李智; 1B-2-12 胡庆访; 1B-2-13 孟伟斯
主题: 答复: 使用CQRS重新考虑架构
看得不是很明白。
对于贫血模式,我也觉得难以理解。既然类里面没有方法,只有Getter,Setter,那么和C里面的Struct,Delphi里面的Record在使用上应该没有区别。但是在实现上,贫血模式是使用类来实现,那么它的创建应该也是在堆里进行,而Struct,Record都是在栈里进行,堆和栈的效率应该是不同的,也就是说EJB是不是为了维持纯粹的面向对象的形式而不顾及效率?
同时,对于只有方法没有数据成员的静态类的设计,这和全局函数应该在使用上没有不同,我知道Delphi的全局函数是直接引址,而类方法(静态方法)应该不是直接引址吧,是不是也因为维持纯粹的面向对象的形式而不管性能了:)
对于查询,我之前所在的公司里是使用小型机+DB2+消息中间件(CICS,MQ或者Web Service)+客户端的方式,后台的查询使用SQL进行,每次只查询一部分数据,其余的用翻页来处理,这和金根提到的懒加载应该想法差不多,对于大数据量的查询和更新,的确可以考虑走别的路了:)
发件人: 3D-1-02 周金根
发送时间: 2009年12月31日 8:32
收件人: 1B-2-05 李智; 1B-2-12 胡庆访; 1B-2-13 孟伟斯; 1B-2-14 穆洪星
主题: 使用CQRS重新考虑架构
这个会简单介绍一下CQRS,http://www.jdon.com/jivejdon/thread/37891,具体还不清晰,但至少能知道DDD中对于查询需要走另一条路