There are many Programming Principles that may seem simple when you first read about them, but when it's time to put them into practice it's a different story. Some principles can apparently clash with others, others are just purely ridiculous when taken to the extreme (Single Responsibility can end up in a class explosion anti-pattern with too many classes with maybe just one method). Some do only apply to certain cases, and don't make sense if used as a rule of thumb (the Law of Demeter is still confusing to me in many cases).
One case that has had me thinking in several occasions is the Command Query Separation vs Method Chaining (Fluent interfaces) one. In principle it would seem like Method Chaining violates the Query Command Separation principle, as you can read here. Yes, you have commands (methods that perform and action and change state) that are also queries (they return values). The thing is, is this really a problem?. I think the main idea underlying this principle (at least the main idea in the wikipedia entry) is: asking a question should not change the answer. Yes, that's also for me the main point, querying data should not modify state. This said, I think that the fact that a command returns state as "an extra" should not be a problem. For example, let's think this in terms of DOM manipulation:
$("#miDiv").append(htmlNodes).addClass("updated");
It's clear that append there has been thought as a command, not as a query that has the side effect of modifying state. You don't use append to obtain the same element again, it's absurd, you use it to modify the element, an as an extra you decide to return the element to facilitate writing cleaner code. So, to me this is not really a violation of the CQS principle.
On the other side, I pretty much agree with what what Fowler says "I prefer to follow this principle when I can, but I'm prepared to break it to get my pop.". It's interesting to note the mention that he does to the Stack class, it also called my attention that Java iterators break the principle (next advances and returns the new value). On the contrary, .Net enumerators don't break the principle, we've got a MoveNext "Command" method, and a Current "Query" property.
We should also have present that there are other cases where this principle doesn't hold simply cause the world that we're trying to model does not follow those rules. Let's imagine a "Person" object with a "GetCurrentThoughts" methods. Calling this method could modify the internal state of the Person, by increasing his "Tiredness" property...
There's another topic that some times comes to my mind related to these matters, the Read Only Property (getter) vs Method discussion. This is because I found sometimes among the list of rules to discern if something should be one thing or the other, that Properties should not have side effects, that is, retrieving a property should not change the state of the object. Well, that is quite useless, cause based on the CQS principle, a method that retrieves a value is a command, and as such should not have side effects either. Regarding this, another interesting point is that properties should not return new objects, you should use a method for that. I also recommend reading this discussion about DateTime.Now being a property instead of a method.
No comments:
Post a Comment