Something I’ve noticed that junior, and often not-so-junior programmers struggle with is how to get started on a problem.

Paradoxically, this problem often gets worse as programmers get more experienced. They’re more aware of potential pitfalls and avenues for future expansion. It’s not uncommon for many programmers to try to code in all the future expansion plans right at the beginning.

Stop. You aren’t going to need it.

Unless you are re-building an existing system, or have highly detailed specifications for the end product, you don’t know how the final system will be used. Furthermore, because it’s a new system, you don’t know what half of the problems are yet. Maybe the routing and security systems are completely new designs. It’s possible that the database won’t handle the load you put on to it - or maybe it’s good for a thousand times as many users as you’ll ever see. You probably won’t know this until you’re building that piece - so don’t worry about it until you’re actually building that part of the system.

In the mean time, solve the problem you have in front of you. Let’s say your building a blog using a new framework that you’ve never seen before. There’s lots of unknowns. How do you load data from the database? How does the routing system turn URLs into called code? Where are users stored in the system? What’s the protection for stopping anonymous users accessing the admin panel?

Don’t worry about all those things. When tackling these problems, I like to break down the system problem into some basic areas, and write these tasks down on a wiki page, or the README.md.

  1. Display blog posts
  2. Show forms
  3. Log in users
  4. Add access controls
  5. Create admin panels

The above list is in a rough order. I need to know how to load pages and pull content from the database before I need to worry about showing forms and processing them. It’s not going to be possible to log users in until I have forms.

Then, I’ll take each task in turn and break it up. The first task might break up like this.

  1. Display text on a static URL
  2. Display text on a dynamic URL
  3. Load text from the database from a dynamic URL
  4. Render HTML from the database from a dynamic URL
  5. Add a rendered page from the URL.

Start with one static URL to return a single piece of text. It doesn’t have to even be HTML. Solve it in the simplest manner possible, and once that’s working, commit that change. At this stage, it doesn’t matter if you’ve solved in the ugliest manner possible, because you now have code that’s known to work, and you can refactor that into nicer code. If you commit as you go with good commit messages, this builds a log of work you can refer back to remind you how to solve problems.

# Examples of commit message fixing one problem at a time.
Commit #1 Create static route to call a function somewhere.
Commit #2 Change test output function to controller.
Commit #3 Pass dynamic URL segment from router to controller as argument and print it out.   
Commit #4 Render different text dependant on the controller argument.
Commit #5 Load a blog object based on the argument passed to the controller.
Commit #6 Add TODO about bounds checking on the blog object ID.
Commit #7 Move the blog loading code from the front end controller to it's own class.

As you work through the problem space, you’re going to discover better ways of doing things and notice various extra tasks. Resist the urge to solve these problems right away. Work on completely the task in front of you, and leave the extra bits for later. In the commit log above, you can see that at Commit #6 I’ve committed a TODO message about a bounds check I need to implement later. Depending on your work flow, you may want to add reminders directly in your code, or you may use an external documentation system. Either way, it’s important to write them down, because you will not remember all the things that you didn’t do properly while you figured how to get that step working. If you put the comments directly in your code then most version control systems, then you can commit just that line1. Committing the TODO lines on their own means that if you have to hard reset back to your last known working configuration, you won’t loose all your notes.

You can also see that in Commit #7, I’ve decided to refactor some of my already working code. When refactoring, it’s important to stick to the mantra of solving one problem at a time. In this example, I have a working task (displaying blog posts) the I completed at Commit #5, but it’s pretty ugly code, so it’s time to refactored. I’ve left this to the end, because until I knew how this code was going to work, there was no point in trying to refactor the huge mess in my front end controller. As you get more familiar with the framework and language you’re working with, this will change, because you’ll know the patterns, and start building these components directly.


  1. For git, this is done using; git add -p ↩︎