RSS Feed

Working with Brownfield Code

Posted on Friday, January 16, 2009 in Features

By Donald Belcham

Donald_BelchamDuring our careers as developers we sit in training courses, conference sessions and vendor demos in which we hear about how easy and great technology XYZ is for creating applications. And almost every one of them assumes that we’re working on new development. I’m not sure about you, but I find that new (or greenfield) application development has been fairly rare in my career.

More often than not, we developers are working in companies that already have a suite of custom software. If you’re brought in to work on a specific project, it’s rare that the project hasn’t had something already started on it. As a result, most developers spend a large part of their careers working with or on someone else’s code. I don’t think this is a bad thing. Instead I think that it is something that we should embrace with good practices, strong tooling and a strong desire to succeed.

If these projects aren’t classified as greenfield, how should we refer to them? One of the most common terms in application development is ‘legacy’. In his highly regarded book "Working Effectively with Legacy Code", Michael Feathers defines legacy code as:

"…code from the past maintained because it works"

I completely agree with this definition, but it does leave us with a gap. Partially completed applications fall squarely in between legacy (maintained and working) and greenfield (not inhibited by past technical decisions or debt). They have incurred some amount of technical debt and are probably constrained by some design or architectural decisions. They also are only partially completed so we’re not working with the code base solely to maintain an already functioning application. Heck, none of the application may function at all yet. It’s these applications that we developers often find ourselves working on.

What is Brownfield?

Brownfield is an increasingly common term being used to define application code bases that are neither greenfield nor legacy. My definition of brownfield is:

" a project, or codebase, that was previously created and may be contaminated by poor practices, structure, and design but has the potential to be revived through comprehensive and directed refactoring".

Brownfield applications exist all over the world, at all companies and in most project teams. Unfortunately they’re the norm, not the exception in our industry. The developer across the world, sitting next to you, and even you and I are all creating brownfield applications on a daily basis.

The fact is that as soon as we write a line of code, we have accepted that we are going to maintain it in that form. No matter how well you write code, you are, at the point of finishing that line of code, incurring some level of technical debt and some level of technical constraint going forward. Every single line of code you write is adding to or otherwise modifying the level at which those debts exist.

These statements shouldn’t scare you. With today’s tools (Visual Studio, Resharper, CodeRush and others) modifying code after it has been created is easier than ever. Refactoring code to lessen the debt or constraints that it places on the project and team is something that is actively encouraged in development circles. There are some things that are important to ensuring that you can do this efficiently and effectively.

Confidence

The largest factor that you need to take into account when working with brownfield code is the confidence level that you, your testers and your client will have with the act of modifying code, without breaking functionality. Nothing scares testers and clients more than the prospect of failing regression tests and bugs introduced to already functional code. It’s not just frustrating for them; it’s also very demoralizing for a development team. As soon as defects are being introduced from what should be innocuous code refactorings, the development team starts to lose confidence in their abilities to manage the code, their abilities to work with the code in its current state, and the their ability to deliver a product to the client. Those things are a well baked recipe for disaster.

I have seen this on projects which I’ve joined part way through their completion. In one case I was working with a team where the developers and the business analysts would physically break into cold sweats when there was mention of having to alter one component within the application. They did anything that they could to avoid having to fix bugs or rework that code. That was a team that had completely lost its confidence.

There are some tools that you can use to build or maintain a team’s confidence. One of them is automated testing. Even if your team is currently confident about its ability to refactor code, creating a suite of unit and/or integration tests will prove to them that their confidence isn’t misplaced. When a team is lacking confidence, adding tests prior to making changes and ensuring that they’re still passing after the changes have been effected will work to rebuild that confidence.

I know that some of you will now be saying that you don’t have the time, resources or budget to build a comprehensive test suite for your brownfield application. You’re probably right. Creating tests after the code has been completed is a laborious task, more so if your project has a significant amount of code. Instead of worrying about comprehensive application-wide test suites, let’s think about them in a more localized and granular fashion.

If you’re looking to rework a small portion of an application to increase its maintainability, work first at creating a good test suite for that small portion of the application. This approach of creating confidence-building tests only for the portions of the application that are going to be changed will allow you to minimize the effort required for creating tests while maximizing the confidence the team has in changes it makes. This approach will possibly never see your application have a comprehensive test suite, but any changes that you have made will be covered by tests.

The advice for creating tests prior to refactoring code also stands true when the team is faced with modifying code to fix defects or to add new functionality. In the case of fixing defects, first creating a test that exposes the bug (and fails as a result of that bug) allows you to have full confidence that you’ve fixed it. Likewise creating tests that confirm new functionality prior to creating the code to implement those capabilities within the application will give you a strong understanding of when you’ve completed the required task.

All Shall Build

Confidence in implementing, fixing and refactoring code is only one part of the brownfield project experience. Confidence on projects comes in many forms. For instance, do you have full confidence that anyone on your project team could correctly compile and deploy your application to any of your testing, staging or production environments? My experience is that there is usually one person on the team who can perform this task and it usually involves a combination of black magic, voodoo and chicken sacrifices.

Why not work towards a scenario where any one of the developers on the team can, and does, regularly create a release package? Traditional methods of compiling applications in the .NET sphere have been limited to "Rebuild All" within the Visual Studio IDE. While there can be some automation included through the use of pre- and post-build events, "Rebuild All" is a largely manual process when you include tasks such as test execution and release package construction. While this can work, it doesn’t necessarily offer the consistency, or flexibility, of using a build script. There are many build scripting tools and languages available to .NET developers. Each offers the same fundamental features, but each also offers a twist.

If you create a compilation, testing and release script that is available to every developer on the team, it becomes one of your projects mechanisms for creating confidence in release management. If the script is available to all developers at all times, they should be encouraged, through simple tooling and fast execution, to run it as many times per day as possible. Every time that you run a script like this you are testing a technically complex portion of your release management process. If that process is being executed tens of times per day, the confidence level of the team and its management and clients should soar.

Social Considerations

We could continue this article with a long and detailed discussion on the merits of using fundamental OO code practices to ensure that your code is flexible, decoupled and robust. Instead I’d like to finish with a brief discussion on the social aspect of working with brownfield applications.

Joining an already started project can present interesting issues both in personal and team dynamics. We all join a new project or job thinking that we can bring greatness to the team or job. As a result we often head into these new engagements bringing suggestions about changes to techniques, tools or practices that we’ve had success with in the past. Unfortunately this usually happens without us taking the time to properly and completely assess the current situation. This lack of understanding around past decisions and current situations, combined with the vocal desire to try to improve things, often leads new team members to be seen in a negative light.

When joining a team we also have to be aware that the currently serving team members probably have an emotional attachment to the current code base. While many developers believe that they are able to openly take constructive criticism of their past or present endeavours, often they can’t. When suggesting changes to a code base, new team members need to be cognizant of the potential negative impact that they may be inflicting on the team’s morale. While this is a delicate situation to have to step around while working to improve code, it is one that is vitally important if the team, as a whole, is going to improve productivity, maintainability and quality going forward. Getting team members to believe in the reasons behind the changes that you’re proposing instead of the changes themselves can be an effective technique.

Many projects that we developers encounter should be categorized as brownfield. While each of these projects encounters its own set of unique issues, there are some underlying problems that are seen on many. Projects might suffer from a lack of confidence in code, releases and quality. They can also have severe maintainability issues caused by poor coding practices. Those technical issues can be some of the easiest to solve, but each technical problem can expose a series of potentially debilitating social and team cohesion issues.

Don’t let any of these issues scare you though. You’re probably already working on a brownfield project and having to deal with many of them. Remember that much of what we do in this industry is deal in areas of confidence between developers and management, developers and clients, and developers amongst themselves.

Donald Belcham is an independent contractor in Edmonton, Alberta, Canada who specializes in software development with the .NET platform.  With more than 7 years experience delivering Web and Smart Client applications to government and Fortune 100 clients in North America and the South Pacific, he has experience and knowledge in the entire software development life cycle.  Combining that experience with his passion for agile development practices and solid OO fundamentals, Donald works to provide the client with software that works for their business.

Recognized by Microsoft for his technical skill and community contribution with the Microsoft MVP award in C#, Donald is a notable leader in the developer community.  In addition to being a founding member, and current President, of the Edmonton .NET User Group, Donald regularly speaks for .NET User Groups and Code Camps across North America on topics ranging from development practices to the intricacies of different technologies.

His thoughts on software development can be found on his blog at www.igloocoder.com.

Bring on the comments

  1. [...] have built a brown field project, which is to say that it has some ugly architectural and coding [...]

  2. [...] sure to read Donald’s article “Working with Brownfield Code“.    Donald Belcham on Brownfield Development [12:54m]: Play Now | Play in Popup | [...]

`

Bad Behavior has blocked 219 access attempts in the last 7 days.