After a lengthy stint of ‘Brownfield’ development I’m moving on to a ‘Greenfield’ project. I thought it’s time for a bit of retrospection.
Contrary to many other fields, the software field tend to look down on artifacts created by others and especially prior to the current times. Terms like ‘legacy’, ‘brownfield’ reflects this fact very well. In Literature people still hold classics such as ‘Shakespeare’ or even more contemporary works to great heights - they discuss these works and let them be studied by newcomers to the field. If you try and compare the same in Software Engineering, which is as creative a process as writing, you don’t see it at all. Which pieces of classic software that we study to learn about our craft or to inspire us?
In architecture and building construction, terms like ‘regeneration’, ‘revitalization’, ‘rebuild’ are considered positive terms conveying a positive message to the listener. However a common software term like ‘refactor’ doesn’t bring that same positive energy to a listener, especially if she’s not a Software professional. What has caused this? Is the insatiable thirst for shiny new things depriving the industry of the chance to look back and appreciate what was achieved before us?
Another factor for this immature attitude towards already created running software could be the on going high percentage of newcomers to the industry. It says that 50% of the industry is having less than 5 years of experience. This is a probably one reason why there’s a lack of love for existing systems and code. It’s hard to appreciate golden oldies when all you have seen is less than 5 years old.
I’ve been lucky to be in both sides of the green and brownfield development for the same application over past few years. I joined the team when the application was being written work for some time, and then left. And then joined the same team when the application is on maintenance mode. So today, while cringing at some of the code and patterns used in the code base, I soon realise that it’s probably me who wrote it couple of years back and then start empathising with that developer - who happens to be me in this case.
The point is, to be successful in brownfield you got to have empathy. You got to put yourself under numerous constraints the previous developer might have had to work under. The constraints could be his own lack of experience, time pressure, lack of functional clarity, technical limitations at the time etc…The common syndrome of this code sucks doesn’t quite work here - because I’ve come to realise that this attitude tends to extend beyond the code. May be you should focus on the code itself and get the individuals who are behind that code out of your mind.
Another good technique of approaching brownfield is to treat it as a sort of detective or investigative work. You have the remains of a case - code - and then you got to draw up whole crime scene. The motives and decisions that went in to the code at hand. The tools at your disposal could be unit tests (even if they turn out to be disposable), knowledge about technical limitations and best practices at the time or even personalities and work patterns of the developers involved in the code base.
A common pitfall of brownfield development is the desire to rewrite - rewrite from scratch. This is equally dangerous for a module or component as much as the whole system. There’s a lot of implicit knowledge hidden beneath that code than you care to appreciate. A rewrite should be taken extremely cautiously, both for technical and business reasons. Most of the time, the men with the cheques don't care a hoot about whether the application is using jQuery 1.5 or 1.9, they just want the defects to be a minimum and system to be performant. So any considerable rewrite has to justify both the technical and business risks. Middle path here is to develop a separate application/module on top of the existing code base and just route the users to this new piece instead of the old one. The old one is still kept for sometime as a mitigation strategy. I’ve found that this strategy gives the business decision makers lot more peace of mind which actually increases the chances of a rewrite being approved in the first place.
Another opportunity to rewrite parts of the system is when a new piece of work (Enhancements) come along your way. This is the chance to get some free testing and strategically do some framework enhancements or component rewrites under the covers.
Almost 95% of the industry is working on maintaining a system. So as an industry, it’s surprising that the amount of resources available for newcomers (Remember 50% of us have less than 5 years of experience) are primarily focused on developing systems from scratch. I hope there will be more resources on how you look after a live system and improve it while it’s kept running.
Probably the first improvement is to making sure that you use modern tools and techniques to look after this system. Again, if you look at the building industry you won’t see builders coming for a repair job of an old 1800 built classic building with just stone knives and hammers. They will have the latest tools. If the code base is not yet ready for that, the first job is to upgrade it so that it’s ready. An example from .Net would be to making sure that the code base is compatible with latest Visual Studio.
A low hanging improvement for these systems is to upgrade to the latest frameworks or to latest servers. Say for a web application, this could be upgrading from IIS6 to IIS8. Without changing any code the users could experience vast improvements.
Sometimes adding value to an existing system is misunderstood to making it look shiny. Although this could get the users attention, that’s probably not a high priority. If you are at early stages in a brownfield project, you might be too scared to propose big changes to the system - fair enough. Focus on what improvements you can do to make your teams life easier. How difficult it is to do a simple defect fix in a particular component. Try and make that component more welcoming to changes. May be you can write a test suite around that component inviting others to contribute and soon you realise that the team is not so afraid to change that component. Another thing is to review what version control the project uses and what kind of workflow is being followed. I’ve come to realise that some teams don’t get the best of version control and that makes them move at a lower velocity. It's not hard to find enterprise developers who had been bitten by using Source Safe and still don't quite get the benefits of having a modern version control system.
An ongoing issue in brownfield is how the implicit knowledge of your team members and code are captured. Do you have 5 year old functional specs that deviates from the current system so much making them useless or even dangerous? What works for our team is a Wiki. It’s a live document capturing bits and pieces of information that’s relevant on a daily basis. When documenting always try and stick to the ‘Whys’ - not ‘Hows’. Documenting why a certain decision has been made is far more important than documenting how a certain functionality works. The ‘How’ is already in the code - make sure your code is readable.
When adding a new feature or doing a significant enhancement always try and stay away from dependencies that are hard to change or obsolete. Instead try and replicate the old piece with new libraries or dependencies and run them in parallel. See how you perform over time and then you can even think about getting rid of the old piece. I've had to do this for some data access components which were dependent on an obsolete version of an Oracle driver. In the interim you might have a bit of duplication in the system, but you always have the long term goal in your mind. This is where software engineering purity doesn't quite get you there, pragmatism trumps purity in these cases.
Brownfield projects should not be treated as doing time for ones sins. It’s a great environment to learn from seasoned individuals and most importantly time tested and seasoned code base. Sometimes learning what not to do is as important as learning what to do.
Make sure you pick a few patterns and practices from the existing code base. Try and document them, since chances are you will forget these in a hurry. One way to do this is to update the existing documentation (wiki) of the project. This will add value to the team as well. Updating the Architecture document, starting a wish list, updating any existing defect records are activities that will leave a positive impression of you among your team members.
Remember it will be so easy for the team (and quite natural as well) to blame you for some of the issues that could arise in the future after you are gone. Make sure that they don’t get that chance. Tidy up what ever little mess you have left unattended. Be it code, documentation or even a rogue folder in your dev server. Be nice to teammates and continue to value their time even after you leave.