Skip to main content

Agile Timeboxing

A few days back, I was discussing Agile Timeboxing and estimation with some developers. What follows are some suggestions I gave them and thoughts that emerged from the suggestions.

In the examples I have used to explain certain points, I have assumed a J2EE application which has a database, an entity layer, an application layer, Struts Action classes, and JSP's. The concepts can be extrapolated into any other type of application as well.


Given a requirement we should be able to determine the amount of time it will take us to fulfill it. This is much easier said than done. Some reasons why we are not able to come up with accurate estimates are:
  • Lack of familiarity with the code base

  • Overestimating our capabilities

  • Underestimating the amount of work needed to be done and it's potential ripple effects

  • Working with gut feel without a proper process to identify the work that needs to be done

In this post I will focus on a process that can be used to identify the amount of work that needs to be done to fulfill a requirement. Once we know the amount of work or it's complexity, the team will have to correlate it to a time frame based on their capabilities.


Let's start with the requirement given by a client. We first need to ensure that it is not very complex and large. If it is, then break it down into manageable sub-requirements. Then break down each of these into tasks. These tasks should ideally be vertical and not horizontal (in your system architecture). So for example, if you are required to modify the design of a few tables and add some business logic, the tasks should NOT be “modify database schema”, “update all classes in the application layer”, “update all Action classes”, and so on. The problem with this approach is, when you modify the database schema, the application will have broken, and will remain unstable until the last task has been completed. It is not a good idea to keep the application unstable for such a long time. Ideally we want the application to come back to stability as soon as possible. Hence, we create tasks along vertical lines, such as “update USER table and support the new field in the view”. This will entail updating the table and all corresponding layers that are affected by that entity. By creating vertical tasks, we ensure that the software will become unstable only as long as we are working on that task. The software will be back in a stable state as soon as we complete the task. A simple rule of the thumb is, a task should not take more than 16 hours to complete. Break tasks that take a very long time to complete, into smaller tasks.


Once we have identified tasks, we have to estimate the time effort. Most of the time developers work on gut feel, but it may lead to extremely inaccurate results. Every task consists of either modifying existing classes or adding new classes. Work your way up the layers of the software and identify all the classes that will have to be modified or added to fulfill that task. For example if we are required to add a new field 'domain' to the login form, we know the USER table has to be modified, and the corresponding entity has to be updated. We then identify all the classes in the application layer that will be affected by the USER entity, followed by all the Action classes and the JSP's. If any new classes need to be created then add them to the list as well. Your IDE can be very helpful in identifying dependencies. After we have outlined all the classes that will be affected or need to be added, we should determine the complexity of work to be done on each class. A simple way is to assign a complexity level of simple, medium, or complex to each class. There are several ways to determine the complexity. One of them is to use the number of unit tests generated to guess the complexity. To understand the complexity, we begin writing unit tests for each class. Since we are still in the estimation phase, we do not have to write the test bodies. It will suffice to write the test methods with a single 'fail()' statement. Be sure that each test, tests one and only one thing, and all possibilities of failure and success are covered by the tests. The number of tests generated will give a fair indication of the complexity involved in updating/creating that class. Since the definition of complexity as well as the team's capability differ, the amount of time a team takes to complete tasks at a complexity level will vary from team to team.


A possible result of this phase will be a table similar to the one below.



Simple

Medium

Complex

Classes

6

2

1

Time (Hrs)

2

4

8

Optimistic Estimate

12

8

8

Multiplication factor

1.5

1.5

1.5


18

12

12

Buffer

20%

20%

20%

Final Estimate

21.6

14.4

14.4


Estimate: (21.6 + 14.4 + 14.4) = 50.4 hrs = approx 50 hrs


The table above shows the effort required to complete a task. We have identified simple changes in 6 classes, medium changes in 1 class, 1 new class of medium complexity, and complex changes in 1 class. Note that we do not differentiate for classes that need to be modified and classes that need to be added. We simply write 2 classes of medium complexity (even though one is to be updated and one is a new class). As we mentioned earlier, every team will have their own correlation of complexity to time. Let us assume that complexity estimates for our team are 2 hours for a simple tasks, 4 hours for medium, and 8 hours for complex tasks. Next we multiply the number of classes with the time. Our first estimate is usually optimistic and must be multiplied by some factor to account for the unknowns like code explorations, technology road blocks (like having to work your way around some potential limitation of Struts), some classes that were missed out in the impact analysis or any other unknown factor. A multiplication factor brings our estimate closer to reality, but in my experience we still have to account for extra time taken due to integration issues, minor requests from the clients, etc. It is usually a good idea to add a buffer of 20% to account for these factors. After applying the multiplication factor and the buffer we add up values in all the 3 columns to get the final estimate.


Once we have estimates for all the tasks, developers are ready to pick them up. In the IPM each developer usually gives his or her available time in the next iteration, and picks up tasks such that they do not add up greater than the available time. We usually assume that all the available time will e spend in coding. We do not consider time spent in client conference calls, email and IM communication, planning for the next iteration, reading necessary documents, etc. The amount of time we will actually have for development is our availability subtracted by time taken for ancillary tasks. Always keep this in mind before picking up tasks.


This is a very practical process for time boxing tasks, that I have often found useful. Several things in this process, like the multiplication factor, buffer, and ancillary tasks are team and project dependent. Appropriate values that better resemble your project and team capabilities may have to be used. The presence of a multiplication factor should not be used as an excuse for lax estimation. It is used to initially account for lack of familiarity with the domain and code base, but should be adjusted as the team gets better at estimating.



Notes: This text was originally posted on my earlier blog at http://www.adaptivelearningonline.net
Here are the comments from the original post

-----
COMMENT:
AUTHOR: Chris
EMAIL:
URL:
DATE: 12/30/2006 05:28:03 AM
I have used a similar technique to estimate. I would simply multiple my gut feel with 3. This almost always produced reasonably accurate estimates.

Comments

Popular posts from this blog

My HSQLDB schema inspection story

This is a simple story of my need to inspect the schema of an HSQLDB database for a participar FOREIGN KEY, and the interesting things I had to do to actually inspect it. I am using an HSQLDB 1.8 database in one of my web applications. The application has been developed using the Play framework , which by default uses JPA and Hibernate . A few days back, I wanted to inspect the schema which Hibernate had created for one of my model objects. I started the HSQLDB database on my local machine, and then started the database manager with the following command java -cp ./hsqldb-1.8.0.7.jar org.hsqldb.util.DatabaseManagerSwing When I tried the view the schema of my table, it showed me the columns and column types on that table, but it did not show me columns were FOREIGN KEYs. Image 1: Table schema as shown by HSQLDB's database manager I decided to search on StackOverflow and find out how I could view the full schema of the table in question. I got a few hints, and they all pointed to

Commenting your code

Comments are an integral part of any program, even though they do not contribute to the logic. Appropriate comments add to the maintainability of a software. I have heard developers complain about not remembering the logic of some code they wrote a few months back. Can you imagine how difficult it can be to understand programs written by others, when we sometimes find it hard to understand our own code. It is a nightmare to maintain programs that are not appropriately commented. Java classes should contain comments at various levels. There are two types of comments; implementation comments and documentation comments. Implementation comments usually explain design desicisions, or a particularly intricate peice of code. If you find the need to make a lot of implementation comments, then it may signal overly complex code. Documentation comments usually describe the API of a program, they are meant for developers who are going to use your classes. All classes, methods and variables

Inheritance vs. composition depending on how much is same and how much differs

I am reading the excellent Django book right now. In the 4th chapter on Django templates , there is an example of includes and inheritance in Django templates. Without going into details about Django templates, the include is very similar to composition where we can include the text of another template for evaluation. Inheritance in Django templates works in a way similar to object inheritance. Django templates can specify certain blocks which can be redefined in subtemplates. The subtemplates use the rest of the parent template as is. Now we have all learned that inheritance is used when we have a is-a relationship between classes, and composition is used when we have a contains-a relationship. This is absolutely right, but while reading about Django templates, I just realized another pattern in these relationships. This is really simple and perhaps many of you may have already have had this insight... We use inheritance when we want to allow reuse of the bulk of one object in other