12 April 2017

Forests and Trees, Mental Exercises for the Practicing Mind

Despite appearances, I'm a pretty focused person. I tend to get a hold of a problem and not let go. In fact, I do this so well sometimes I forget the bigger picture. 

Once upon a time, far, far away I was commuting to Florida weekly for a job. The hotel thing got tired real fast, and it was also very expensive. So I got an apartment. I stocked the place up with rented furniture and a nice TV, but I didn't feel like buying new computer equipment, so I shipped my printer and a few odds and ends from home. It seemed like a sensible plan, but I wouldn't do it again. The printer showed up in 4 pieces and I could not get it working again. The shipping agency had simply poured packing peanuts into the box, taped it shut, and sent it. (Last time I'll pay them to pack and ship). I bought insurance on the package, so when I found the remains of my printer I snapped a few pictures, call them up and tried to execute my claim. No dice, the package was not properly constructed and they wouldn't pay; despite the fact that they had packed the box, not me. There label was even on the box. Still no go.

I was livid. Anyone who knows me is aware that inconsistencies like this can send me into a hyper active ranting state about the lack of justice and proper behavior in the world, usually followed by a tirade on free-markets. 

In this case I really got lost. I had a solid contracting gig working 40+ hours a week at a very high rate. Rather than going to work and making some money I spent the first 3 hours of my work day on the phone with the shipping company trying to get my insurance claim accepted. That's right, I spent three (potentially billable) hours talking to customer support. I went so far as to document everything, get the address of the CEO, write, print, and mail a letter of complaint. I was going to get my consumer justice. (I never heard back from them, but I refuse to ship with that organization to this day). 

This was pretty foolish. I lost out on a few hundred dollars of billable time over a printer that, when new, cost me about $150. It wasn't new when I shipped it, I could just have bought another one. Heck, I could have gone to the mall at lunch, picked up a comparable model AND eaten a burger, without skipping a billable beat. But instead I got lost, staring at the trees and forgot about the forest. I stopped my lunacy at lunch time and that is when a buddy pointed out what I had just done. I felt pretty dumb.

In the end it was a good learning experience. What I learned that day was that I'd been looking at the trees and not looking at the forest. In the end it was just a printer, a good one, but no sentimental value at all. 

In reflecting on this event I found that I have, once or twice, done the same thing with development work. I get so focused on what I'm doing that I forget to back off and look at the forest. For example, I might write an elegant looking piece of code and decide that that pattern needs to be applied throughout a system. I then happily run off and track down every place where I can make my glorious improvement to the system. I'm focused on that tree. The forest however says, the system works and doesn't necessarily need fixing. In fact, my fabulous, wonderful, hyper-elegant piece of code should get reviewed by at least one more person before I run around 'fixing' the system with it. For that matter, even if upon review it is deemed worthy, I should consider the iteration goals before I allocate time to propagating my genius creation. Bigger still is the consideration of the release goal, the timeline, my social life, and my need for sleep. It might be better to declare my discovery a good lesson learned, stash it in a gist someplace for later reference, and move on. 

We often get obsessed with things like perfection and correctness and all the various clean code rules that we love and revere so much, but many of these things, in a business sense, are the trees. The CIO doesn't care deeply that your code is DRY, or that you've properly applied the Visitor Pattern. The CIO cares about serving the business and/or customers with software that works. The business as a whole is more of less oblivious to the details of our craft. Those details, compelling as they are, really matter to us, the people who live in the code and have to deal with it daily. And the reality is, beauty is in the eye of the beholder. So my precious nugget of super compact, well named, DRY/SOLID/Clean code is indeed a spectacle to behold, but has no genuine value outside the realm of developer-dom. 

If we, as software development professionals, really want to get awesome results for the business, we need to think about the big picture along with the details. We need to step back and consider the impact we are having on the whole organization with whatever we do. I used an example of a 'special block of code' here, but it could be anything from a naming convention to an application architecture. We need to consider how its development and enforcement will impact the organization as a whole before we trot it out as 'the answer' to any problem. 

Here is a little trick I now use to help myself decide if I should proceed with some task. Before I begin I set out very specific objectives for the task and then I ask myself, how will that help us achieve goal X. Where X is any one of the organizational goals. I often have to ask this question a dozen or more times for a dozen different Xs. When I do this, I then know I've considered the impact of my actions (present and future) on the organization as a whole and I can proceed with confidence. If I cannot answer a question, I know I have to do more work. It might be as simple as saying to my pair partner, What do you think with respect to X? Or I might need to talk to a product owner or the Director of Engineering. 

If you keep asking yourself these questions periodically you will develop an intuition for the correct behavior within the context of a project or job. Here is another tip, consider when your context changes. The answers to your questions might change depending on the context of what you are doing and from whom. For example, if I'm developing course work or a tutorial, I might spend hours agonizing about the correctness of a solution, but if I'm developing a spike I might only take a moment to make sure it works. Why, because the answer to the question 'will I need to reuse this?' is yes in one case and no in the other. 

Last tip, if you don't know what questions to ask, ask a meta question like 'What is important to the organization with respect to this thing?' Try your answers out with others to validate that you've asked good questions, and then solicit questions from them to help you build a better understanding of what questions you should be asking. 

You might be asking what are the Xs. Well it depends somewhat on the specific task but here are some examples...

Does this further the objective of the current task/objective?
Is this aesthetics?
If this is aesthetics, are they worth while? Do they lead to understanding or is it just pretty?
Does this further the iteration objective?
What are the long term consequences of doing this? Did I just create cruft/tech-debt?
Can others understand what I've done and why?
How does this impact the current release? Will this cause a delay?

I think you get the point.