In my last editorial, "A Software Pre-Mortem," I discussed a new project my team was just starting. It’s now been a bit over two months and the project is beginning to pick up real steam. The team picked up an additional developer and is about to add ten more people. Yes, you read that right; we’re going from a six-person development team to a 16-person team.

Our goal is to take the lessons we learned in the early phases of this project and apply them to a much larger development team. In this editorial, I want to discuss a few things we’ve learned and how we intend to apply these lessons to a larger team.

In 1975, Fred Brooks documented the challenges of adding numerous developers to a project too quickly in "The Mythical Man-Month.

Learning What We Didn’t Know

When we started this project, the development team chose several forms and processes from the legacy system that represented functionality and would be spread throughout the project. Some of these were "simple" data entry screens. Others were complex business processes and others were parts of more complex features. The purpose of this phase of development was to ferret out a general idea of what was missing from the framework. We found numerous gaps in the framework and in our process.

Conversions Need Analysis and Design

When converting projects, it’s very tempting to just take a feature and start to convert it right away. We learned very quickly that this wouldn’t work well when going from one code base to another. The legacy system (20 years old) had incurred a lot of technical debt due to its design. Throughout the legacy codebase, code was tucked away in every "nook and cranny." This means that code could be found everywhere from abstract classes, to individual event hooks, to external modules and third-party tools. When building a feature, it’s difficult to ascertain where the code you’re converting really lives. Adding to this challenge is the fact that the new architecture is a multi-layered application with the MVVM pattern being used for the front end and a service-oriented architecture on the back end.

We adopted a new process before development could start on converting features. We needed to spend time doing a thorough examination of the legacy code base and finesse those features into our current layered architecture. We developed a rough outline of what each developer needed to do. The basic outline is as follows:

  1. Analyze functional documentation and screens
  2. Describe what the service needs to do and its goals
  3. Extract all repository calls (stored procedures)
  4. Create an interface of repo methods
  5. Design a service that will achieve goals of the feature
  6. Create the interface
  7. Extract all user interactions
  8. Alerts
  9. Yes/No
  10. Other user prompts
  11. Review and approval of design by senior developer

Conversions require special attention to the details found in the current code base as well as the documentation. Having developers go through this process makes it more likely that details aren’t missed. Another benefit of this process is that managers get a better idea of feature sizing; what might have seemed simple is often more complex or vice versa.

Documentation and Training Are Paramount

I believe that a frequently overlooked aspect of development is documentation and training. I also believe that the quickest way to achieve productivity is to provide developers with good documentation and training. During the initial phase of the project, we had a few sessions with all of the developers to train on the various aspects of each project. We spent time demonstrating new tools, and new framework features and concepts. We discovered that we could deliver huge productivity gains by having these training sessions. Every developer found these sessions rewarding and now they’re becoming a regular part of our development process.

Creating "The Way"

It’s funny, the things that trip up developers. Here’s one I found to be profound: the deceptively simple concept of where to place a file in the project solution. The question: When I create a new entity (class, view, view model, service, repository, etc.) where should I put it in the solution structure? When building large scale applications, this really matters. We must have a standard way of adding elements. As a matter of fact, we must have a standard way of adding everything to the project structure. As the saying goes, we need "A place for everything and everything in its place." It was during the initial phases that we standardized file locations.

Of course, it’s not only file locations that are important to standardize. It’s important to standardize how parts of the application will interact. We specified how modules would communicate with each other, and where the user interface elements would go versus the service elements. This became known as "The Way."

Measuring Progress

This project is of a critical nature to our client and our stakeholders have placed a priority on how this project progresses. We’ve gone through several fits and starts when it comes to tracking progress and just recently came up with an acceptable solution. The beauty is that the tracking solution we chose matches "The Way" I mentioned above.

Every software project I work on presents its own unique challenges and this project is no exception. The sheer size of this project required new tools, techniques, and methods. It even required a wholesale new way of tracking progress as previous projects didn’t have the scope and scale of this one.

The most important aspect of this project so far has been flexibility. Each day presents new challenges and it’s flexibility that rules the day.

This issue has been largely written and reviewed in collaboration with Microsoft and Microsoft employees from the ASP.NET Core team. For more on their work, check out: