So, here is a snippet from a class that parses and evaluates arithmetic expressions.
public class Solver1 {
private String input;
public Solver1(String input_) {
input = input_.trim();
}
private boolean consumeIf(String s) {
if (!input.startsWith(s))
return false;
input = input.substring(1).trim();
return true;
}
public double eval() {
double lhs = multiplication();
if (consumeIf("+"))
return lhs + eval();
else if (consumeIf("-"))
return lhs - eval();
return lhs;
}
private double multiplication() {
double lhs = unary();
if (consumeIf("*"))
return lhs * multiplication();
else if (consumeIf("/"))
return lhs / multiplication();
return lhs;
}
...
}
Looking at consumeIf() we note that it violates the CQS principle. This method is a query (it computes and returns a result - either true of false) which is also a command (it changes the value of a field). Let's see the looks of the code after decomposing consumeIf() into two methods: a query and a command:
public class Solver2 {
private String input;
public Solver2(String input_) {
input = input_.trim();
}
private boolean nextIs(String s) {
return input.startsWith(s);
}
private void move(int numChars) {
input = input.substring(numChars).trim();
}
public double eval() {
double lhs = multiplication();
if (nextIs("+")) {
move(1);
return lhs + eval();
}
else if (nextIs("-")) {
move(1);
return lhs - eval();
}
return lhs;
}
private double multiplication() {
double lhs = unary();
if (nextIs("*")) {
move(1);
return lhs * multiplication();
}
else if (nextIs("/")) {
move(1);
return lhs / multiplication();
}
return lhs;
}
...
}
There is a 25% increase in code size, 42 vs. 33 lines of code, but I will put this aside because I think that #LOC is not a very good estimate of code quality. (Actually, I don't believe in any code quality metric)
Nonetheless there is a another issue which is much more significant: in the second program we have this recurring idiom of calling nextIs() and then calling move(), as in: if (nextIs("/")) { move(1); ... }. These two calls are mutually dependent: the parameter passed to move() must be the length of the string passed to nextIs(). This idiom is error-prone as the programmer may accidentally change one of the parameters while leaving the other intact.
This shows that arbitrarily applying the CQS principle may yield bad results. A good programmer should be aware of that and should make judgment calls rather than blindly following principles. In fact, this happens a lot with many other programming principles. They are usually much closer to guidelines (and therefore require judgment) than to absolute rules. I think that Lars summarized it pretty well: "I generally dislike '-isms' because they set up rules that people try to apply without understanding the preconditions that need to be met."
Hi
I find using CQS to be more useful to public methods than to private ones.
Your eval method does voilate CQS and i think it is more problematic than asking yourself if nextIf should be divided into 2 functions...
If you decide to use nextIs and move you could minimize a risk of programming errors by changing move method to take a string param (the one you would pass to nextIs) instead of int.
One thing that hurts me more when thinking of CQS is fact that i would like to return success/faiulure from my commands. The simplest solution is to throw exception in command if exception occured but exceptions tend to clutter code too much.
milus
April 15, 2010 at 1:45 PMHi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me. I am a regular follower of your blog.
Really very informative post you shared here. Kindly keep blogging.
Java training in Btm layout
Java training in Rajaji nagar
Java training in Kalyan nagar
Java training in Kalyan nagar
Java training in Jaya nagar
siva
February 2, 2019 at 9:52 AMI read this post two times, I like it so much, please try to keep posting about java & Let me introduce other material that may be good for our community.
sap training in chennai
sap training in tambaram
azure training in chennai
azure training in tambaram
cyber security course in chennai
cyber security course in tambaram
ethical hacking course in chennai
ethical hacking course in tambaram
Jayalakshmi
August 18, 2020 at 8:07 AMGood Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve
my knowledge as updated one, keep blogging
hadoop training in chennai
hadoop training in porur
salesforce training in chennai
salesforce training in porur
c and c plus plus course in chennai
c and c plus plus course in porur
machine learning training in chennai
machine learning training in porur
praveen
August 19, 2020 at 3:54 PMGood Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve
data science training in chennai
data science training in omr
android training in chennai
android training in omr
devops training in chennai
devops training in omr
artificial intelligence training in chennai
artificial intelligence training in omr
deiva
August 21, 2020 at 4:43 PMVery excellent post!!! Thank you so much for your great content. Keep posting.....
Best Tableau Training Institute in Pune
Apache Spark Training Institute in Pune
Prwatech
March 23, 2021 at 2:25 PMkartal samsung klima servisi
ümraniye samsung klima servisi
beykoz bosch klima servisi
üsküdar bosch klima servisi
beykoz arçelik klima servisi
üsküdar arçelik klima servisi
pendik samsung klima servisi
pendik mitsubishi klima servisi
beykoz vestel klima servisi
Anonymous
June 3, 2022 at 1:51 AMSuccess Write content success. Thanks.
kralbet
canlı slot siteleri
canlı poker siteleri
deneme bonusu
betturkey
betpark
betmatik
kıbrıs bahis siteleri
December 26, 2022 at 3:34 PMamasya
antakya
edirne
elazığ
kayseri
Q88
batuhan
July 31, 2023 at 12:03 PMsalt likit
salt likit
dr mood likit
big boss likit
dl likit
dark likit
0NLB7D
Tuna
August 12, 2023 at 10:21 PMhttps://saglamproxy.com
metin2 proxy
proxy satın al
knight online proxy
mobil proxy satın al
5FAVP
sude
August 29, 2023 at 10:30 PMhttps://saglamproxy.com
metin2 proxy
proxy satın al
knight online proxy
mobil proxy satın al
F0C
İlayda
September 9, 2023 at 8:37 PM