Earlier this month, I spoke at the Prairie DevCon in Regina, SK. The last day was a fantastic all day seminar on Brownfield Development by Donald Belcham, coauthor of a book on the topic. A Brownfield project occurs when you have an existing application that you are actively updating and fixing. Sound familiar? It should. Most of us work on Brownfield projects. Greenfield is brand new development on an new product. A legacy project is one that you rarely update, providing only critical bug fixes. In this post, I will summarize the seminar and hopefully give you some valuable information to help with your project and reduce technical debt.

The most important thing to remember when working on a Brownfield project is “Context is King”. In other words, always ask yourself, “Self, why did they do things the way they did?” By asking this question, you’ll understand much about the project and how to best enhance it.

Step 1 in your process is getting an automated build going. This is the single biggest thing you can do to improve your process and improve the application without touching the code. I’ll come back to this in a moment.

Step 2 is to run automated tests. Many QA departments run automated tests, but do you have automated unit testing? You nott have any unit testing or very little or not testing the proper areas of your code. Identify the trouble areas of your code first and devise unit tests for them.

Step 3 is to get your release package inot your automated build. Creating and testing the release package should not be a manual process. There are too many things that can go wrong in a manual process. It’s too easy to miss things or even include things that should not go out to the customer. Also, make sure your install scripts and other release tools, scripts, and artifacts get put into source control.

Does your product include a database? Are you managing it well? Do you have scripts to create and alter the database schema, create stored procedures and functions, security, etc? Are those scripts in your source control? Do you have automated testing setup on those scritps?

How is your development environment setup? Do you have it virtualized so that one version of the application doesn’t interfere with another?

I assume you are using Source Code Control (SCC), but are you using it properly? Do you know all the capabilities of your SCC tool? Do you know how to do everything the SCC tool does? What about branching and merging? Is it simple? Can you do it? Does it case great pain? Is it difficult to merge code from one engineer with that of another? How often do you check in? By checking in frequently, you will reduce merge problems.

What is your automated build, or even better, are you practicing Continuous Integration (CI)? [Note: I am coauthor of the book "Continuous Integration in .NET"]. You’ll get immediate feedback on your project, which will reduce risk and help you make a better product for our customers.

If you take on a new Brownfield project, the first thing you should do is look at the build script, release management processes, etc. You’ll learn alot about how the application is built and prepared for the customer. Next you should run the tests in the code. This will show where code issues may exist. If you get lots of problems with these items, odds are you’re in trouble already on the project.

When fixing bugs, identify the pain points and devise unit tests. Look for fear in the eyes of current team members when you suggest modifying code in a particular module. This fear tells you that they don’t want to touch that code because it is very brittle and will break with the smallest of code changes. These are areas that can benefit most from unit testing.

Do you have unit tests and are your running code coverage to know that the unit tests are really testing the code efficiently?

Are you doing proper defect analysis? Things like bug counts don’t tell you much. You need to look at areas where bugs come from. Does one module get more bug reports than another? Are bug reports coming from QA or from customers. These are the things that tell you the most.

Is the application well architected? (Odds are it isn’t according to today’s standards.) When you hear about three tiers, that refers more to a physical layout. Layers is more logical. Look at Domain Driven Design to help out here as it greatly simplifes complexity.

The UI layer should use a standard UI design pattern such as Model-View-Controller (MVC), Model-View-Presenter (MVP), or Model-View-ViewModel (MVVM) in the case of Silverlight and WPF.

The business layer should be divided up into different layers itself with Services (connecting to external resources, but not data), Translators (data processors), Domain Model (business rules), and Repositories (data access/store) making up the main concerns and aspects cutting across them. For example, a logging utility, that’s needed by all the concerns. In a .NET environment look at something like Castle Windsor to make it easier to handle aspects.

What kind of data repositores are you using? Are you using a relational store, and if so, do you use some type of an Object Relational Mapper (ORM) such as the .NET Entity Framework or NHibernate? Are you calling web services? Is the data RESTful? Is the data in plain text, XML, or .ini files?

WOW! That’s alot of stuff to consider and deal with. So, how do you cut through all the chaos in your Brownfield application? You have five options:

  • Horizontal layers – not very appealing from a technical standpoint.
  • Module by module – not a small undertaking
  • Bottom up – In this case, you start to update the data access layer and move up to the UI
  • Top down – start at the UI and move down to the data access layer
  • Slicing – probably the most appealing. Take one very small piece of functionality, for example, save a patient record, and rework all the code needed to do that, from UI to data access.

What about your code? Is it good? Is it DRY? Are you practicing YAGNI? How about SOLID? Do you practice Separation of Concerns? These are all techniques to make your code easier to read and maintain.

Do you use Design Patterns? Do you stay away from the Singleton pattern, that is probably the most elitist pattern in the world?

Finally, are you improving confidence that your code, and the application are good? Here are some things you can do:

  • Reduce regression errors
  • Make it know that what you’re doing is difficult
  • Do integration tests
  • Refactor your code
  • Add unit tests
  • Know that it’s 100% fallacy that you will ever get 100% of your code under test. And you shouldn’t care. You only need to test the things you need confidence in.
  • Set your direction and know where you are going form here.
  • Do code katas to improve your coding skills

If you want to know more about Brownfield development, there are two books that have very valuable information. The first, Brownfield Development in .NET, is by the guy that presented the seminar, Donald Becham. Don’t let .NET in the title scare you away if you aren’t doing .NET development. All the concepts apply, it’s the tools that are different. The second book is Working Effectively with Legacy Code by Michael Feathers.

You can survive Brownfield development. With the concepts and tools these two books present, survival may not only be easier, but you may thrive in a Brownfield application.