Mike Knepper

Work in the Present

April 29, 2014

One of my tasks this week is to remove a feature from my Clojure Tic-Tac-Toe app. This requirement, along with some other work I’ve started this week, has me thinking about working in the present.

Planning the design and architecture of an application in advance is important, but it is very easy to think too far ahead and over-engineer a project. For example, I built my Clojure TTT with a variable board size option (meaning you could set the number of rows/columns on the board rather than always play on a standard 3x3 board) from the get-go. However, Rylan never explicitly required that feature in an IPM. Fast forward to last week, while optimizing my minimax algorithm to improve performance, I had trouble getting the optimization techniques to work correctly for both 3x3 and 4x4 boards. Rylan noted that he never actually asked for a 4x4 board, and in fact only cares about a 3x3 board for this implementation. As a result, I’m now spending time stripping out a feature I mistakenly assumed would be a requirement. Needless to say, undoing something is not exactly the kind of work we want our clients to demand of us.

Another feature I’m working on this week is Spanish language support. The idea is to provide for some config file, likely written in YAML, to hold Spanish translations of all the prompts and be easily loaded in to the system to run the game entirely in Spanish. I was running into an obstacle this morning that was greatly over-complicating my code and causing quite a headache. Eventually, though, I realized that I was making the same mistake: assuming in advance that some feature (in this case, a particular prompt) would be necessary even though it was never written down and agreed upon as a requirement in an IPM.


There are a few takeaways from these experiences. First, on the positive side, ripping out the 4x4 option demonstrated a nice feature of the Open/Closed Principle “in reverse,” so to speak. My TTT board was originally written flexibly enough to allow for different sizes without modifying the code–it received size input from some other function responsible for asking the user what size he or she wanted. I was able to remove the 4x4 option in such a way that the board is still flexible, but the user simply does not get an option to change the size. In other words, the board and related functions (ex. determining the indexes of winning paths algorithmically based on board size) remain Open/Closed Principle-compliant despite not actually taking advantage of that flexibility at this time. Going forward, I will need to pay attention to building modules in a way that complies with the SOLID principles even if a requirement that SOLID helps facilitate isn’t expected yet.

Second, there is an important business lesson here about consultancy work. As a consultant, I need to be sure to follow the explicit requirements laid out by the client. Obviously not completing those requirements is unacceptable, but going too far beyond those requirements with extra features is problematic as well. Someone in charge–a project manager, CEO, customer, whoever–needs to budget time and money and run some kind of schedule for the project. To do this, they need to understand what they’re asking of the development team and what pace is sustainable for that team. Going overboard with features during one iteration might set an unreasonable precedent for a future, more difficult iteration. Additionally, although good consultants are intelligent and well-informed about the client’s industry, the client still presumably knows more about their business needs. As with the 4x4 option in my TTT game, a feature that seems cool to the developer may be unnecessary or even harmful to the product or project in a way only the client understands.