How to write clean code, practically

People often talk in the abstract about refactoring while writing code. But doesn’t that mean you just have a huge pull request with lots of unrelated changes muddled together? Or worse, several separate pull requests that conflict with each other?

It doesn’t have to be like that.

There’s an exercise I’ve used with great success which trains you to write code in the right order. It’s called Baby Steps. You start a 2 minute timer and start making your change whatever way seems sensible. When the timer goes off, if you have compiling code with green tests you may commit, otherwise revert. After all, you’re only losing 2 minutes of work. The idea is not to get faster at pressing the keys the next time around, it’s to learn what was blocking the change you tried to make, and focus in on that next iteration. You might need to keep note of why you’re doing various tasks and how they fit into the bigger picture – this methodology was formalized by the Mikado method.

When doing this, you’ll often find you’ve written a whole sequence of changes which are pure refactors*. You could pull request and merge them without actually changing the behavior of the application, but they change the shape of the code to make space for the feature/bugfix you’re currently working on. By the end of this process, your feature/bugfix can be a simple single-line fix. You should also find you hit the timer less often as you get used to identifying smaller problems mid-way through and resetting early. I’m not going to say you should always work to a 2 minute timer, but I’d certainly advocate the overall style of development. Taking turns at driving when the timer goes off works great in a pair to keep you both engaged. Note that this doesn’t replace other methodologies. If it’s a big change, spike it. Still use TDD, BDD or whatever you’re using this week to drive your development.

To summarize, use pure refactors* first to make space for your the changes you’re working on. Then make your behavior changes separately. Baby Steps is a great way to practice doing this that works on real code.

Refactoring an API? Try Expand, Migrate, Contract refactoring.

* By “pure refactor” I mean that the behavior of the application doesn’t change. I haven’t added features or taken them away. I would advocate all refactors being done this way, but recognize the term “refactor” is sometimes used just for general code changes.
Thanks to Alastair Smith for pointing out the links that inspired this post
Advertisements
Posted in Uncategorized | Leave a comment

Rewriting Git history

The other day I made about 30 commits to a project without realizing my editor was adding spaces to the files even though they mostly contained tabs. I really couldn’t care less whether files have tabs or spaces, but consistency is the important thing, so I decided to rewrite my history to convert them using this command:

 git filter-branch –tree-filter “git diff –name-status master HEAD | egrep ^[AM] | grep .cs | cut -f2 | xargs sed -i \”s/    /\t/g\”” master^..HEAD

git rebase master

Git basically checks out every revision of the repo into a directory. I then use git diff to check which “.cs” files were new or modified in the range I’m rewriting, which I then pipe to sed and replace four spaces with a tab. The reason I go from “master^” is so that rebasing onto master will have a commit at the start which normalizes the endings of all the files I’m about to change – though you’ll probably want to reword that commit with an interactive rebase later!

Hopefully you can see the four spaces and \t which can be flipped round to do the opposite conversion.

Posted in Note to self | Leave a comment

Hypothesis, Measurement, Decision

“Build Measure Learn” is a popular mantra from the Lean Startup world and it’s a great way to structure things. There’s extensive advice on getting it right, unfortunately though, to me, the words don’t have the right connotations when condensed down like that. So here’s how I think of it:

Hypothesis

X% of [specific potential customer segment] need/desire [specific value proposition]
Imagine you already have the results, would it let you decide what to do next?

When aiming for product fit, a nice way to find an area of focus is by plotting your assumptions on a risk matrix, evaluating the impact and likelihood of being wrong.

Measurement

The quickest/cheapest way to get feedback
e.g. Survey? Ask users to sign up if they’re interested?

If the answer seems like “build it”, figure out how you’d make people aware of the thing you built, and how you’d get evidence of your hypothesis from that. Ask yourself, do you really still need to build anything for that plan to work? Or could you just tell people you’re thinking of building it and ask them to make a commitment such as giving you their email address or time to prove their interest?

Sometimes the answer really is “build it”, so build the smallest thing that could give someone in that customer segment just enough to see the value proposition and give you the feedback you need to proceed.

Decision

Summarize learning, shuffle priorities, set the direction to go next, then start the loop again.

 

Using it

Hopefully it’s pretty obvious how to follow this step-by-step when you have 1 big idea and 0 products on the market. You find the best way to test the assumptions behind that idea, and reshape the idea based on that learning until the best way to learn more is to implement that idea. This can work very similarly for new features.

Once you establish a customer base and need to make tweaks and bug fixes you can use the same framework, but choose your area of focus based on customer retention rather than product fit. You will likely already have some evidence for the “measurement” part.

Sometimes the expected implementation+maintenance cost is below the cost of further research. In which case:

  • Make sure you deliver some value as early as possible to give you a chance of changing direction when you’re wrong, or when the world changes under your feet.
  • Identify the measure of your success. Imagine you’ve shipped the wrong thing, then pick a hypothesis that would let you know which assumption was faulty or what to do next. Make sure you’re collecting that data!

 

 

I like to think this blog post provides a small chunk of value. I’ll be watching for page views and messages to decide whether to delve deeper at a later date 😉

 

Posted in Note to self | Tagged , | Leave a comment

My Git setup on Windows

GitExtensions – Free, cross-platform Git UI giving good visibility of the relationship between commits/branches while providing the power to achieve most everyday functions (commit, merge, interactive rebase, and many more)

Tip: During installation, choose the option which integrates with the windows command prompt by adding Git’s user\bin directory to your PATH.

PoshGit – Contextual information in powershell about the current branch

Tip: Set an environment variable GIT_SSH to be “C:\Program Files\Putty\PLINK.exe” to use putty for SSH from Powershell.

 

Posted in Note to self | Leave a comment