Note: I use the word ‘component’ a lot in this article. By that, I mean a vague term for a small chunk of UI and functionality. Some frameworks and libraries use Component as a class, I’m not referring to any of those specifically.
When doing work for clients, you have to provide an estimate. They need to get budgets ready, plan for release dates, have people ready to use the new site or application to give feedback and report early bugs. Estimating the work that goes into a software project is, by large, a matter of experience. Over time, a developer will build up an understanding of how to guess the effort a single component will take and what effort goes into connecting that component to other parts of the application.
Once you have a model, you can decompose it into components. You’ll need to discover the mathematical rules that describe how these components interact. Sometimes a component contributes a single value that is added into the result. Some components may supply multiplying factors, while others may be more complicated.
Andrew Hunt, Dave Thomas: The Pragmatic Programmer
To estimate a component, you need to be able to see all the parts. If you can’t see all the parts, the component is too big and needs broken down. For example: a client has a document sharing application and needs to add searching functionality. That can’t be estimated with any accuracy, so we need to break it apart. What does searching include? A search form, sure. How much time does it take to add a new page, or add a field to a persistent piece of UI (like a header)? That’s one part. How much time to create a route and controller for the search form to submit data? That’s another. On and on, until each piece is broken down into a manageable chunk. This makes it easier to grasp and guess ‘roughly how much time to build this?’
Sometimes, estimating a component’s effort means actually creating a roughed out version of what you need to build. Back to the search example, if you’ve never built a filter for a list of results before, it might be a good idea to try a quick example. Don’t solve every piece of it, that’s a waste of time. But if it takes you thirty minutes to scratch out a decent working example with some static data and an ugly UI, it’s possible that thing won’t take more than a few hours total. Otherwise, if thirty minutes barely scratches the surface go ahead and assume days, not hours.
One understanding that comes with experience is the general level of complexity that the component has — and based on that level of complexity, how much extra time needs factored in. When I build estimates, I call this my “unexpected buffer” time. Back to the search filter example again: The client is fine with a full page refresh whenever some new filters are added. Simple to build, not a lot of complexity. Now, let’s assume the filtering and sorting needs to be instant, but that entire search result needs to have a shareable URL. This is a level of complexity that can introduce unforeseen problems. We still give both components an estimate according to the effort — but each one also receives a buffer time. Low complexity, add 10% to the estimate. Maybe 20%. Highly complex, add 50%. I’ve gone so far as to double my estimates.
The buffer is the unsung hero of my estimating process. It keeps launches on time and saves everyone’s sanity. And, if you don’t use it — your client gets an early delivery, which I guarantee they will love.