Originally posted by Bryon Phinney:
A question I have is will the "Input translation" know about the Operator objects. Restating - should there be a OOCalc.in(Operator operator) method?
I've been thinking about this a little too, but it is several steps ahead of the game
Originally posted by Bryon Phinney:
Can anyone give some direction on what constitutes a small step.
Originally posted by Steve Fahlbusch:
Are we assuming that we have have not discovered
this yet (and will so when we get there)? ie, the
5 + 5 + 5 {test}) or do we know this, but only
adding what is needed for each individual "requirement"
as it were?
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Originally posted by Michael Matola:
Almost posted along similar lines last night (yeah, yeah, right), but what I was writing got so long I decided to set it aside for a day and come back to see if I could shape it up.
Very short version --
The main issue I had was that the " return 0.0 ; " at the bottom of performOperation() was unreachable, given the current clients of the code, and should be refactored away somehow. The duplication between getResults() and performOperation() didn't bother me as much as the unreachable return because I figured they'd eventually get combined when we implement the factory. Also, I was going to rail that in getResults() the "else" was redundant and the condition was the wrong way round, that it should be the following, so the unusual case returns earlier than the standard case.
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Originally posted by Michael Matola:
Depends. I've been thinking about this a little too, but it is several steps ahead of the game. At this point I think it's clear were working towards a factory method that will determine which operation to perform (or place on a stack for later execution) by using some symbolic constant to pick a concrete subclass of an abstract Operation. Whether those symbolic constants will be Strings in OOCalc, such as our current ADD, or, say, typesafe enumerations held in Operation that have specific subclasses of Operation as instances (as you've suggested) is really up in the air at this point. I guess at some point the decision will come down to what code we'll want to let know about the subclasses of Operation -- the Operation class itself or OOCalc's in() or getResult().
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Originally posted by Terry McKee:
Second, I am by no means an expert, but it seems to me that having two return statements is not a good idea. I really believe that OO code should build on Procedural code. That means in this method there should be one entrance (the method call) and one exit (the return statement).
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Originally posted by Ilja Preuss:
Does anybody know where the "one exit" rule is coming from? How is it motivated?
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Originally posted by Ilja Preuss:
As a side effect, in almost every case I find some data and/or behaviour to move into the Enumeration class afterwards, transmogrifying it into a State/Strategy.
Originally posted by Junilu Lacar:
Throw me a bone here guys. I was hoping somebody would have caught it by now but I'll give another hint: Duplication is a bad code smell. See if you can find any duplication in the refactored code in OOCalc, Step 9. Take a look at getResults() and performOperation().
[ March 26, 2002: Message edited by: Junilu Lacar ]
Originally posted by Ilja Preuss:
Just found http://c2.com/cgi/wiki?SingleFunctionExitPoint
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Originally posted by David Weitzman:
How does test-first programming scale to something more complex though?
"A complex system that works is invariably found to have evolved from a simple system that worked...
Originally posted by Junilu Lacar:
So, when we talk about scaling to a more complex problem, we simply fall back to the good old "divide and conquer" approach. Then we do test-first development on the simpler pieces and slowly evolve towards the complex, ruthlessly refactoring along the way. Test-first forces us to start simple while refactoring helps pave the way for evolution and gives courage and capabilities to handle more and more complexity.
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Originally posted by Michael Matola:
2. Code duplication.
The perform() methods of all subclasses of Operation share the same identical code:
double op1 = ( (Double)operandStack.pop() ).doubleValue() ;
double op2 = ( (Double)operandStack.pop() ).doubleValue() ;
Looks to me that instead of passing the Stack into perform(), we should be passing the doubles that we've already popped.
That change would give us the following perform() signature in Operation:
public abstract double perform( double op1 , double op2 ) ;
A sample implemenation in Addition would be:
And the calling code in OOCalc would be:
And we could also switch the order of assignment while popping:
So we wouldn't later have to switch the operands in Subtraction and Division.
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Originally posted by Ilja Preuss:
But you just have moved the duplication, not removed it, don't you?
Originally posted by Michael Matola:
You and I are talking about different duplications, Ilja.
I wasn't complaining about the fact that these two lines
double op1 = ( (Double)operandStack.pop() ).doubleValue() ;
double op2 = ( (Double)operandStack.pop() ).doubleValue() ;
between them share the same code for popping, converting, and casting. (You've shown that there's probably not much to gain by trying to remove that duplication.)
Take a look at those perform() methods: all four of them first get the doubles from the stack, then perform the actual arithmetic. What I'm suggesting is that the code to get the doubles from the stack be moved elsewhere.
My above suggestion was to move that code into to the client method OOCalc's getResult() (which would involve a change in interface: perform() would accept two doubles as parameters instead of the stack).
Another possibility would be to refactor the common double-getting code from the various perform()s into the superclass Operation, with perform(Stack operandStack) becoming a concrete method that first gets the doubles, then calls the abstract perform( double operand1 , double operand2) which subclasses implement. (Vaguely template-methodesque.)
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Joy is a radiation