How not to become the maintenance developer

As a developer it seems, you always seem to strive towards producing ever more complicated code. Utilizing new frameworks, adopting an ever evolving “convention before configuration”, pushing object-oriented programming – maybe Domain Driven Development – are practices introduced, refined and explored in the quest to prove yourself as a steadily better developer with rising skills.

Workstation

Yet to what point?

While the intricate complications may impress fellow developers, doing so often digs a hole which may be pretty hard to get out of. Every complication – not matter if it is in the design, the architecture or the structure of the code – often provides the opposite effect of the desired outcome. The whims of your current self to impress developers with the latest fashionable technique, is short termed reward for a long term pain.

I accept some fashions and whims do change and solidify to become better practice, often the urge to over use the latest and greatest frameworks, techniques and paradigms, often only leads to a painful maintenance in years to come – and as you’ve complicated things beyond comprehension you’ll probably be the trapped in the maintenance for the lifetime of the developed code.

Keep It Simple

As new development challenges often are much more fun, than maintaining legacy code, there are a few basic things you can do to keep yourself from being the eventual eternal maintenance developer and they are straightforward:
Keep it simple
When solving a problem, make as simple and as little code as needed. Don’t wrap everything in object hierarchies, split configuration, views, models and controllers in individual files – do it only, when it provide clear and apparent value.

Names matter

Choose short, but descriptive names for variables, functions, classes and objects in your code. An object containing content for an invoice should be named $invoice, not just $x, $y or $z. Using naming of artifacts in the code provide clues to content and functionality makes it much easier for anyone – including your future self – to comprehend and understand the code when doing maintenance.

Don’t fear comments

Comments does not slow down your code. Al code is compiled at the latest at run-time and a few well placed comments may often be very valuable for the eventual maintainer. Don’t comment obvious code constructs (“don’t state the obvious”) , but do reference business rules or why something tricky is going on.

Be consistent

Find a consistent way to solve the same task/pattern every time, as it will help you focus on what the code is doing instead of the syntax expressed. If you during development find a better way to do something, remember to go back and fix the instances where applicable.

Move on…

Every developer will eventually be stuck with some development, but making your code accessible and easy to understand – the odds of you being stuck forever on maintenance duty is much lower. Great code move on from the parent and have a life on it’s own in the care of other developers if you’ve done your job right.

Are you ready for transparency?

Running a modern IT platform is rarely an easy nor isolated task. Most platforms consist of a fairly large number of components ranging from OS level to 3. party libraries and components added in the user interfacing layers – and adding numerous integrations does make it an interesting challenge to quickly identify and correct bugs and errors.

While the system complexity does pose a challenge is surely not an impossible task, as several tools exists for most – if not all – platforms to allow instrumentation of the platform and utilize the instrumentation tools to handle the platform and identify issues quickly.

Instrumentation provides insight…

Instrumentation tools are generic tools which allows you to identify errors in your production environment and provide sufficient context and debug information to allow developers to diagnose, understand and fix the issues identified. Examples of such tools include AppDynamics, New Relic, Stackify and many others. If you’re the Do-It-Yourself type, it’s not unfeasible to build a tool yourself by hooking into error handlers and other hooks exposed by the specific platform due to be instrumented.

Having worked with various degrees of instrumentation for 10+ years – homebuild and purchased tools, I can certainly confirm that such tools works and allows you to mature a complex IT platform much quicker, as the insights provided from a live production environment allows you to attack the most occurring errors experienced by real users of the system.

Test suites are great for minimizing risk during development, but the test suites are based on assumptions on how users and data acts in your platform,  and while the identified errors experienced over time certainly help minimizing risks in new development, it is “theory” as opposed to instrumentation which is much more “practice”.

Heimbach - power plant 12 ies

 

Transparency not needed

While the tools to do instrumentation for most platforms may readily be available, the “natural use”  – even in an enterprise setting – seems surprisingly low, and I suspect numerous reasons exists.

We do not need it is often the most common. As set procedures exists and they seem to work, why would we need to introduce a new tool to provide data we already have. Error logs, end-user descriptions and screenshots have been used for decades and why should there be a better method?

It introduces risk is another often cited concern. As instrumentation tools are not considered a need tool in the IT platform, operations may oppose to adding it to the already complicated stack – especially if the value of the instrumentation is not known or recognized.

It is expensive is another misconception. Instrumentation often don’t provide any direct business value (assuming your IT platform isn’t burning and the users is leaving rapidly). Most of the value offered by instrumentation tools is fixing issues faster and the scope of issues  being smaller, and as such it’s often hard to prove the value offered by issues not occurring.

Transparency not desired

Apparently many people believe firmly, that issues not seen nor reported are not real issues, and does not exist. Gaining insights into one instrumented platform and running a black-box platform next to it, may  cause the false belief that the black box system is running more stable and with fewer issues than the transparent system.

The reason is simply that on black box systems (that is systems without any instrumentation tools to monitor their actual performance) it is rare to proactively examine logs files and other places where the black box might emit issues. Only when an issue is reported, developers are assigned to examine these sources to resolve the issue.

Gaining insights into an IT platform though instrumentation and being able to resolve “real” issues as experienced by your users should be a fantastic thing, but beware that many people implicitly seems to believe, that with you don’t monitor for errors and issues, they probably doesn’t exist – however false it is.
See No Evil, Hear No Evil, Speak No Evil

Accidental Architecture

Most IT departments have the best intentions of providing the best quality, coherent solutions, yet market conditions, projects running in parallel and various constraints on budgets, resources or time, often causes what might be defined as Accidental Architecture.

The easiest way to identify cases where you’ve been hit by accidental architecture is when describing your it architecture and look for the works “except” or “but not”. Typical examples include – we have a single-sign system utilized everywhere except…”, “We update all systems to current versions, but not this old system…”.

The accidental architecture seem to be caused by a few main drivers:

  1. Lack of overview
  2. Lack of time
  3. Lack of resources

Lack of overview

When the root cause is lack of overview, the case is often, that decisions and designs are implemented without understanding the entire scope of the problem – or existing procedures and architecture in place. While a good coherent architecture seems to have been designed, it turns out that existing complexities which wasn’t known or addressed causes issues.

Lack of time

Deadlines often seem to be the cause of many issues – and no matter who much time you may a assign to a project, you’ll often need just a little more. As a deadline approaches often shortcuts a made to make the deadline and the shortcuts – which is assumed to be fixed in the next version, but often forgotten and abandoned – until issues arise.

Lack of resources

The issues caused by lack of time and lack of resource may seem similar, but are different. When lack of time causes the issue, the problem could have been solved, whereas lack of resources often happens when budget constraints or lack of knowledge causes an architecture to be chosen which may not be the right solution of the problem at hand.

The lack of resource issue may often occur, when projects are expected to drive enterprise changes – merging billing systems, decommissioning legacy platforms and other issues, which should be done, but often a product development project may not be able to facilitate.

The first step, is to realize there is a problem…

While many organizations fail to realize the existence and the volume, most actually seem to have a fair share of them – and if not handled – probably a growing volume.

Once you’ve realized you have cases of accidental architecture, make sure you address them on your technical debt list and have plan for what to do about the system. While “pure” technical debt most often may cause operational issues, the accidental architecture usually cause customer facing issues and are not recognized as severely as the operational issues caused by technical debt.

The issues introduced by accidental architecture is often complexity, slowly rising operational costs and increased user-support costs. To keep your IT domain alive and moving forward, time and resources must be found continuously to address and resolve the accidents.