These two snippets are from the JDK source code:
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;
}
Command-query separation (CQS) states that every method should either be a command that performs an action or a query that returns data to the caller, but not both. Do these two snippets from the JDK source code violate the CQS principle?
Yes, the code you've quoted is an explicit violation of Command-Query Separation as defined by Bertrand Meyer, who coined the term in 1988 in Object Oriented Software Construction. CQS forbids any routine that has side effects from returning a value - even a status code to indicate success or failure. The only CQS-compliant way to communicate such status codes would be to have the "Command" set the status code somewhere where a subsequent "Query" can retrieve it.
In section 4.7 of his book, Meyer distinguishes between "procedures", which may not return a result, and "functions", which do return a result:
He goes on to define the Command-Query Separation principle as follows in section 23.1:
This is explicit. It is not a vague suggestion that your routines should either "do something" or "retrieve some data" but not both. It is an explicit requirement that routines either have no side effects or no return value.
It should not be surprising that the JDK violates this principle, because CQS is not widely accepted. Meyer himself remarks in his book:
I had not been born when he wrote his book, but his remark remains true three decades later. Whether the blame for this properly lies with CQS being impractical or with programmers' dominant practices being impure is a question I leave to the reader.