Goal #6: I wanted to plan for change, in scope, in the composition of the development team, in technology and in time lines.
Change on a project is inevitable. Even on short projects of a couple of weeks, there will always be a small change that causes some consternation amongst the team. I was conscious of four types of change:
1. Scope.
Everyone has dealt with this one. You can’t fight it. The best way to deal with it is to track it, to have good processes for handling it, and for providing feedback to management and the customer as to how each change in scope will affect the project.
Prior to the start of this project, our change tracking was minimal, if nonexistent. We used a web product called Gemini for tracking bugs and some feature requests for existing projects, but we didn’t track deliverables and tasks for new projects getting started. We used VSS (horror of horrors) for our source control. It was quite clear that as an organization, we were outgrowing these tools.
We made the decision to try something else as soon as the project was announced. We had access to Team Foundation Server and Visual Studio Team System Team Suite without needing to spend a bunch of money, so we used that. It was a big step forward from VSS, and it took quite a while to get up to speed on how to use it, and how to use it properly. There were definitely some very painful moments, and we’ll all be glad when we can upgrade to TFS 2010 to get things like hierarchical task trees and better integrated reports. We went back and forth on the best way to use the system, and I think, at the end, we were doing the best we could, though there are more features that we can probably gradually integrate into future projects to make us more efficient. We didn’t take advantage of the Estimate / Actual / Work Completed feature, and that is the one thing I would really like to change on the next project, to not just get a picture of how many tasks are outstanding, but how we are tracking effort to the goals. It would also greatly improve our ability to provide feedback to everyone when a scope change comes in to see how it really affects the project time line. Right now a ten minute bug fix carries the same weight as a 40 hour feature implementation on the task list, and that is obviously misleading and wrong.
2. Team Composition
We only had one change in the team in terms of losing someone from the team from beginning to the end of the project, but we did gain two new people as well. On a small team, it’s essential that in one person’s absence or departure, that another can step in and fill that role, or at least be able to understand what that person was working on so the work does not come to a grinding halt. The only way I know how to do this is for everyone to be doing things the same way. If everyone uses the same tools, writes code to the same standards, there’s a lot less chance that code will be a mess when someone turns it over. I harped a lot to the team about a couple of things in particular
a) Everyone had Resharper and was expected to make that little light at the top of the file go green every day. Okay, part of this is due to the fact that I am anal-retentive when it comes to clean code, but part of it is a matter of enforcing standards. I can’t sit over every developer’s shoulder and watch them name their variables, and set their tabs. But Resharper, and the lovely Ctrl K D really left us with some pretty clean code. It’s amazing how much easier it is to work on someone else’s code when you are not scared to open the file.
b) Nightly Builds: We used TFS to do our nightly builds, right from the start, and constant check ins were encouraged. Everyone feared the words ‘Who Broke the Build? UNACCEPTABLE!” being shouted across the office.
c) Unit Tests: As previously discussed, we could have done much better here, and we are working on making this better for the next phase.
d) Unity: We used the Unity Application Block for dependency injection (DI). I’ll go into more of the Unity overview in a later post, but because we had Unity set up early in the project, we were able to create mock objects and able to swap code in and out easily so that itwo people were rarely dependent on one another’s work. This was especially important prior to bringing on the new people to fill a void in some of the back end code areas so that UI development could proceed until they were up to speed.
I also spent some time creating a ‘Technical Overview’ document that summarized some of the technical decisions we made early in the project, some of the issues that were left to be resolved, and a quick reference for some of the more complex processes we were using. I don’t know how much this helped the new guys, but it made me feel better that I had at least tried to help them come up to speed without them needing to spend a week constantly asking questions we should have documented.
When I started my first IT job back in 1994, my boss gave me ownership of the New Employee Orientation / Standards book, and told me to update it when I found a question it didn’t answer, as I would be handing the book off to the next new person, who would then come to me first to ask questions. I love this chaining of documentation pattern. It gives the new people immediate ownership and responsibility. Of course, some people weren’t as robust in their documentation as others were, but if we held true to the pattern, everyone would see the benefit of keeping the document up to date. It made sense back then, anyway.
3. Technology
We knew the technology was going to change, and change rapidly during this project. Managing this change was a constant challenge. Again, Unity and DI played a large role in helping to resolve this issue. There were many times where we had issues with Azure, or did not know where the data would actually reside at the end of the project, but that didn’t stop the developers from continuing their work. We built interfaces and mocks, and swapped the managers in and out using the configuration files.
During most of the project, there were only two of us who ever touched Azure, just to insulate the team from the environmental changes. We defined the processes and worked through the issues, but the rest of the team barreled forward, not needing to know the specifics of how the system would work on Azure. This was true for deployments, data storage, security and configuration. Almost everything we built could run directly in IIS7 or in the dev environment without Azure being available. Pieces were converted over to run on Azure one at a time as they were ready with a few configuration changes. I can’t emphasize enough how important this is when working with dependencies that are constantly changing. Isolate them, mock them, keep the team moving.
4. Time Lines
The final date was not moving, but that didn’t mean that there wouldn’t suddenly be a need to give a quick demo of what we had to the customer in the middle of a big dev cycle. The builds saved us there, and having two (I would have preferred 3) environments to run the app in from early in the project allowed the devs to keep working, while the ‘PROD’ site was only updated as we achieved more stable releases. Having the multiple environments saved our bacon more than a few times.