I'm starting my new job today and kicking off a new project this week. The organization is relatively new and this is the beginning of their first .Net product. Other than some interesting integration needs with an existing backend, the project is greenfield. Everything has to be built from scratch. Jeffrey Palermo was trying to talk me into keeping a Jim Shore-style diary about this project and my experiences. I think I'll try to do that too, but in the meantime, here's my initial thoughts on how to get the project rolling. As usual, I'm viewing the project through the Agile paradigm.
My consistent experience spanning companies, teams, and processes is that projects that start with energy and write useful code early are far more successful and smooth running than projects that take a long time to get going. Establishing momentum and a sense of energized work are essential for a successful project. Going back to my first "real" programming job I saw both extremes within a year. On my first project we started with excitement and energy by building a demonstrable prototype and got the business behind us immediately. There was a sense from day one that we were going to do something good. To this day I still consider that project the most successful I've ever been on (and no, it wasn't an Agile project). On the second project we started by doing 6 weeks of "current state analysis" and worked another 6 weeks to (in)validate the consultant's recommendations. That project got mired in analysis/paralysis for months and never delivered a single line of working code. Complete and utter failure.
I honestly think it's more important to start early and seize some momentum for the project rather than spend more time getting the vision perfected. Even if it's just architectural spikes, I want code being written very early to get a sense that the project is real and moving. I'm pulling this figure out of thin air, but my hope is to start writing production code within an iteration structure in about two weeks. In physics, the effect of friction is greater on a resting body than a moving body. Software development is the same way. Get going.
Step #2: What are we building?
Step #1 is "steal underpants." Step #2 is to get a handle on what we're building. We know that there are some specific architectural risks that need to be spiked, but without a direct connection to the immediate business need, that technical work may be purely speculative and potentially wasted. The technical work must be grounded in the actual business priority.
I think the most important thing upfront is to start creating a common vocabulary (ubiquitous language) around the business problem for the team. Agile processes are usually built around expansive communication between team members. The fastest way to foster that communication is to develop a ubiquitous language. For example, what are the business entities, transactions, and user types called?
From a purely project management perspective, I think the critical path is going to be creating a story backlog of requirements. The requirements need to be enumerated and fleshed out just enough so that we can go into the Release Planning meeting. Iteration 1, and development in earnest, cannot start until we have a release level collection of prioritized requirements (user stories) with rough estimates. I'm not too worried about having the first set of stories detailed out upfront because the first iteration is always slow as you deal mostly with architectural and design issues.
Learn the Context
These days there's basically no such thing as an application that lives in isolation. Most applications live inside the context of an existing IT infrastructure. One of the first things to do is to start learning about the context of the system. What other applications will it need to interface with? Who manages these systems? How do you get your needs onto their project or iteration plans (big concern of mine at the moment)? Is there existing data that needs to transferred? If you're doing a rewrite, where is the old code? What are the technical constraints of the client? What's the overall strategy of the company, and how does this new system fit into that strategy? I'm in the middle of trying to understand just those questions.
Iteration #0: Prepare the Field
On a project 2 1/2 years ago we lost half of the first iteration to problems with CVS issues (CVS is right behind VSS in my source control enemies list), partly due to my ignorance. That was one of many issues that set a bad tone for the project right off the bat that we didn't ever entirely shake. I'm never doing that again. From that moment on my projects have always started by solidifying the software ecosystem first.
When day 1 of iteration 1 rolls around I want to be able to focus on coding and design, not fiddle around with setting up build scripts, source control, and test environments. To make the most of your time, work an Iteration #0 that takes place to do the "NAnt-y" work to prepare the field for development. Iteration #0 can take place in parallel with building the story backlog. By the start of Iteration #1 I'm suggesting that we have:
- A source control repository already in place that everyone knows how to access. We're going to be using Subversion (free, solid, easy to use)
- Shell of the project solution, including a project for unit tests and another for integration tests. We'll probably take advantage of TreeSurgeon to bootstrap the effort.
- Binaries of the development tools (NAnt, NUnit, RhinoMocks, etc.) the team is going to use checked into the source control repository. I like to put these in a folder called "bin", other people call it "tools." Under no circumstances do you ever count on these tools being installed into a workstation's GAC!
- An initial build script (probably NAnt delegating to MSBuild for the compile) that:
- Cleans out older build products
- Versions the code according to the current build number
- Runs unit tests and integration tests (NUnit most likely)
- A little bit later we'll add test coverage with NCover and code metrics with NDepends
- Get CruiseControl.Net setup to run the builds from day 1. Continuous Integration needs to be engrained from day one, and besides, it's easier to do it upfront and let it evolve with the system than it is to retrofit later.
- Everybody needs to have the CruiseControl.Net system tray client to monitor the builds
- Get the ancillary tools (ReSharper, TestDriven.Net, TortoiseSVN) installed on the development machines.
- Research tools for acceptance test automation. Normally I'd say FitNesse/FIT right off the bat, but I'm going to look at some WinForms specific tools like SharpRobo and NUnitForms.
A Social Contract for the Developers
Right off the bat the team needs to start creating a "Social Contract" for the way they're going to work. This contract includes thinks like:
- Naming standard for projects and assemblies
- Agreeing on some sort of "Check In Dance". Build hygiene needs to be socialized through the team. This is a good point to make sure all of the team knows how to run the local builds and access information in the Continuous Integration builds.
- Coding standards (keep it light)
- Where to put unit or integration tests and how to name test fixture classes
- What tools to use
- Initial design strategies. I wouldn't get carried away with this, but right off the bat I want to talk about using the Model View Presenter (Passive View & Supervising Controller) patterns.
- Are we doing pair programming, and what percentage?
- Are we mandating Test Driven Development (if I have my way, yes)?
- Get a Wiki page going for the project
- Get a Story Wall setup somewhere easily visible
- Figure out where we can do standup meetings without irritating the rest of the office
- Logistics of pairing — hardware, desk setup, etc.
- Create a Risk Management list somewhere equally visible
A team's definition of "this is the way we do it" will, and probably should, change over time as the team learns and adapts. It still helps to start with a small core of project conventions and working standards.