讨论一下CQS (命令-查询 分离)原则

:D 看Craig Larman的书,
里面提到的这个原则.

请看下面两个函数:


// style #1; used in the official solution
public void roll()
{
faceValue = // random num generation
}


public int getFaceValue()
{
return faceValue;
}


为什么不是将两个方法合并, 使roll()方法返回新的faceValue呢? 如下所示:


// style #2; why is this poor?
public int roll()
{
faceValue = // random num generation
return faceValue;
}


你可以发现大量使用风格2的代码的例子, 但这种方法并不合适, 因为它违反了[b]命令-查询分离原则(Command-Query Separation Principle)[/b]. CQS是针对方法的经典OO设计原则. 该原则指出, 任何方法都可能是如下情况之一:
1. 执行动作(更新,调整...)的命令方法, 这种方法通常具有改变对象状态等副作用, 并且是void的.
2. 向调用者返回数据的查询, 这种方法没有副作用, 不会永久性的改变任何对象的状态.

关键是, [b]一个方法不应该同时属于以上两种类型[/b].

[color=red]CQS被公认为计算机科学理论中具有价值的原则.[/color] 因为遵守该原则, 你能够更容易的推测出程序的状态, 在查询状态时不会同时发生变更. 这样使得设计更便于理解和预见. 例如, 如果一致遵循CQS, 那么你还知道查询或者getter方法不会作出任何更改, 而命令也不会有任何返回. 这是个简单的模式.[color=red] 这通常是要严格遵循的[/color], 因为如果突然采用其它方法, 将会产生令人不快的意外, 从而违反了OOD中的[color=red] 最小意外[/color](Least Surprise) 原则.
[color=green]<from Aply UML & patterns>[/color]

以上是原文, 昨晚上看书时才看到的, 回想起来以前真的好多次违反这个原则,
但不确定这个原则是否所有情况都适用,
大家怎么看CQS的, 我本来想找出例外情况的, 但一时还没想出例子来, 一起讨论下吧.

--------------
好像清楚一点了, CQS更像准则, 而不是"原则",
会有例外情况出现的, 比如jdk中:


// FileInputStream
public native int read() throws IOException;

// Vector
public synchronized boolean add(E e)

// HashMap
public V put(K key, V value)


看来学习OOD理论不能太死板,呵呵
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值