If you’re not interested in reading through this post, but would like to be a mentor on my next C# project, please connect with me! Let’s write a program together!
148 lines of code, 12 commits, 6 public comments on Github, and about 12 total hours of programming/collaboration. My first C# project, a console tic-tac-toe game, is at a point where I’m comfortable calling it “done”. (Author’s side note: this is also my first program written since 2005!)
Every award winner loves to give thanks, so I’d like to express gratitude for Deborah Lee — my “team member” and project mentor — and Daniel Albuschat for being a collaborator through Github. It was awesome learning from both you!
This post describes a novice’s thought process for refactoring, what changes I committed to feel “done”, and my concluding thoughts on this project.
Between this post and my prior project entry (with a significant delay incurred due to holiday madness), I received a number of comments from Deborah and Daniel that resulted in refactoring, which I’ll discuss:
- Naming convention.
- Moving logic to validate user input into a method.
- Operator usage (&, | versus &&, ||).
Plus my own realization that wasn’t provided by either collaborator:
- Refactoring the “CheckWinner” method to ignore X & O, instead checking for grid-space equality to determine if a game has been won.
Daniel left me a comment on Github that pointed out my use of CamelCase was inconsistent. He observed that my methods and properties started with a lowercase letter, e.g., “myMethod” – rather than “MyMethod”. While this must have looked confusing, it was very much by design! The online C# lessons I took as part of my initial self-study routine suggested that the C# community uses different formats of CamelCase to denote private versus public methods – specifically, private methods begin with a lowercase letter.
privateMethod (begin with lowercase)
PublicMethod (begin with uppercase)
Admittedly, I didn’t find any sample code from various public repositories that seemed to match the same naming convention, so when in Rome…
Next, Daniel introduced me to a function in Visual Studio that seems extremely handy: the “Extract Method” option.
In a prior commit, I checked-in a couple comments that explained some of the more complex code written when Deborah and I pair-programmed together. Daniel observed that complex validation logic could be extracted to a method to be both easier to read – and easier to document. Eager to see “code magic” performed before my eyes, I fumbled around until I uncovered the option and allowed the IDE to write code for me.
(This seems as good a place as any to mention that the last lines of code I wrote were written through a VI editor. And “committed” by moving directories around in AIX so someone could manually merge code at some unknown point in time. And then walked ten miles home in snow.)
It seemed slightly unnecessary to move just a single line of code to its own method, but reflecting back on the change, I understand the principle. While the game in its current state today isn’t going to win any awards for complexity, what if tomorrow my users demanded a different format for providing input or new gameplay options? I know exactly where to look in the code and, if there were multiple entry points into the logic, could make changes in one centralized location.
Now that I’ve had some time to think about this recommendation, I’m reminded of a simple analogy from Jason Kerney:
If your garage is a mess and you need a certain screwdriver, you might know exactly where to look. After all, it’s your garage and you’re the only one going in there with any frequency. But what happens once you start sharing the garage or, worse yet, have an emergency and cannot go into the garage yourself? If other people cannot clearly see how the garage is organized or quickly self-navigate to find the screwdriver, the act of finding it becomes unnecessarily painful (and potentially risky).
Next, Deborah noted that my logic to check the winner of a game used “&” and “|”, rather than “&&” and “||”. Letting my novice status out on full display, I still don’t understand the difference between & and && in the context of my method. I’ve reviewed the documentation on MSDN and it seems the greatest advantage is moving to “||” will prevent further checking of other conditions if true. This seems like a good thing. I’m just putting my trust that Deborah knows way more than me.
Lastly, as I invested a bit of thought into my code and let the tangible nature of working software do its thought-magic, I realized that two separate IF/ELSE IF blocks to check winning conditions for “X” and “O”, respectively, were totally unnecessary. Instead, I could simply check for equality (e.g., grid locations 1, 2, and 3 are the same) and look to the total number of moves to see who won (e.g., if even number, the computer player has won). Humility be damned – I’m pretty proud of myself for discovering this! The lesson here is: “now I know how best to do it” is so much easier when there is working, tangible code in front of you.
This was fun! It’s not going to change lives or disrupt a trillion-dollar industry, but I wrote a working software application in C# with my own self-study and collaboration with intelligent people. I learned a lot about what it’s like to be “in the trenches” that helps give me perspective on team coaching, especially with respect to safety and vulnerability in doing knowledge-work among peers. Further, the lessons that Agile teach us for dealing with complexity are real: smaller is better, emergent design is a powerful mechanism to discover what works, and when accountability exists in a team… teammates want you to succeed.
I’m ready for my next project! Do you want to collaborate with me and continue my self-study adventure of programming in C#? Let’s connect!