Today I was working on my GUI and one of my goals was reducing the complexity of the method that was in control of which game was to be played, while at the same time making it more flexible to change. Because I had never used the Qt framework prior to this project and my knowledge in terms of event-based programming was limited, the first version of the play
method looked like this:
Needless to say this is bad. A case statement can often be a sign of a smell and here that was indeed the case. This method has a bunch of conditionals and even a conditional within a conditional (until). It’s hard to change and it definitely violates the OCP principle since if I wanted to extend it in any way, I’d have to open the method and modify it in order to add the new game type.
I discussed this with my mentor and he pointed out most of the above, suggesting that I remove the computer_vs_computer
option, clean up the design and then add it again. After working with it for a bit and simplifying things more, I arrived at this:
Better but still that long if statement bothered me quite a bit. Then I turned to a tool Ruby provides yet I had never used until now, the lambda
.
What I essentially did was to store each game type into it’s own lambda, then set an instance variable to the chosen lambda and execute/call it when the time is right. The resulting code looked like this:
So now when the button is pressed the appropriate method gets triggered which sets the @game_choice
variable to the correct lambda and when the user clicks on a cell at the end of that method, it sends a message to the play
method which in turn calls the lambda with the correct argument:
There’s still plenty of work to be done but at least now I can add more types of games to it if need be and taking away the case statement and the until loop is definitely a win. I discovered a bunch of interesting things about lambda
and Proc
during the process which I will try and document in another post tomorrow.