JDK 源代码是否违反命令查询分离 (CQS)?
Does the JDK source code violate command-query separation (CQS)?
这两个片段来自 JDK 源代码:
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false; }
public boolean add(E e) {
ensureCapacityInternal(size + 1); // increments modCount
elementData[size++] = e;
return true;
}
命令-查询分离 (CQS) 规定每个方法要么是执行操作的命令,要么是 returns 向调用者发送数据的查询,但不能同时是两者。 JDK 源代码中的这两个片段是否违反了 CQS 原则?
add
和 remove
都是改变状态的方法,而不是查询。他们 return 一个有意义的结果。我不认为这违反了 CQS。问题是 CQS 会给这些操作带来什么价值。
是的,您引用的代码明显违反了 Bertrand Meyer 定义的命令-查询分离,他于 1988 年在 Object Oriented Software Construction 中创造了这个术语。 CQS 禁止任何因 returning 值而产生副作用的例程 - 甚至是指示成功或失败的状态代码。传达此类状态代码的唯一符合 CQS 的方式是让 "Command" 将状态代码设置在后续 "Query" 可以检索它的地方。
在他的书的第 4.7 节中,Meyer 区分了可能不是 return 结果的 "procedures" 和 return 结果的 "functions":
“Procedure” will be used in the sense of a routine which does not return a result, so that
we have two disjoint categories of routine: procedures and functions. (In discussions of
the C language the term “function” itself is sometimes used for the general notion of
routine, but here it will always denote a routine that returns a result.)
他在第 23.1 节中继续定义命令-查询分离原则如下:
Functions should not produce abstract side effects.
这是明确的。这并不是一个模糊的建议,您的例程应该 "do something" 或 "retrieve some data" 而不是两者。明确要求例程要么没有副作用,要么没有 return 值。
JDK 违反这一原则不足为奇,因为 CQS 并未被广泛接受。迈耶本人在他的书中评论道:
As you may have realized, this style is very different from the dominant practices of today...
他写这本书的时候我还没有出生,但他的话在三十年后仍然是正确的。这是否应该归咎于 CQS 不切实际或程序员的主导做法不纯是我留给 reader.
的问题
这两个片段来自 JDK 源代码:
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false; }
public boolean add(E e) {
ensureCapacityInternal(size + 1); // increments modCount
elementData[size++] = e;
return true;
}
命令-查询分离 (CQS) 规定每个方法要么是执行操作的命令,要么是 returns 向调用者发送数据的查询,但不能同时是两者。 JDK 源代码中的这两个片段是否违反了 CQS 原则?
add
和 remove
都是改变状态的方法,而不是查询。他们 return 一个有意义的结果。我不认为这违反了 CQS。问题是 CQS 会给这些操作带来什么价值。
是的,您引用的代码明显违反了 Bertrand Meyer 定义的命令-查询分离,他于 1988 年在 Object Oriented Software Construction 中创造了这个术语。 CQS 禁止任何因 returning 值而产生副作用的例程 - 甚至是指示成功或失败的状态代码。传达此类状态代码的唯一符合 CQS 的方式是让 "Command" 将状态代码设置在后续 "Query" 可以检索它的地方。
在他的书的第 4.7 节中,Meyer 区分了可能不是 return 结果的 "procedures" 和 return 结果的 "functions":
“Procedure” will be used in the sense of a routine which does not return a result, so that we have two disjoint categories of routine: procedures and functions. (In discussions of the C language the term “function” itself is sometimes used for the general notion of routine, but here it will always denote a routine that returns a result.)
他在第 23.1 节中继续定义命令-查询分离原则如下:
Functions should not produce abstract side effects.
这是明确的。这并不是一个模糊的建议,您的例程应该 "do something" 或 "retrieve some data" 而不是两者。明确要求例程要么没有副作用,要么没有 return 值。
JDK 违反这一原则不足为奇,因为 CQS 并未被广泛接受。迈耶本人在他的书中评论道:
As you may have realized, this style is very different from the dominant practices of today...
他写这本书的时候我还没有出生,但他的话在三十年后仍然是正确的。这是否应该归咎于 CQS 不切实际或程序员的主导做法不纯是我留给 reader.
的问题