Simplicity in code
You start with a complex, untidy, difficult to comprehend or maintain system. The plans for fixing it somehow involve adding more code to the system. Additional layers of abstraction, new interfaces supposedly to decouple the components. Sound familiar? Why is that simplifying a system requires adding more? Much of the time it shouldn’t.
Take a step (or several) back and look again at what the system or platform is supposed to do. Forget for a moment how it goes about doing it. Data processing. Most of the time, we write systems to take input data streams, manipulate and record them, and produce output data streams to outside parties. Most of the time the shiny platform we are devoting so much resource to is a glorified pipe.
What does that pipe actually need to do? Forget the bells and whistles - just the core business value. Now think about all the additional ‘features’. Do they really serve enough of a purpose to justify their effort? Also take a look at all the additional code which isn’t actually delivering the business value - the communication frameworks, the layers and layers of abstractions just in case, the unnecessary generalisation of the problem being solved, again just in case. How much of the codebase falls into that latter category?
I’d say that most of that code can be binned. How much of the architecture exists to support the architecture as opposed to supporting the core business function? Complexity begets complexity.
Many times when faced with a system that has grown like this until it reaches breaking point, the choices are to refactor by adding, scrap the system and start from scratch, or simplify. I strongly favour the last of these. Refactor by deleting code - as much as you can get away with. Each layer of complexity trimmed away generates a clearer view of what the system was initially intended to do, and provides opportunities for further removal of unnecessary code. It’s not uncommon to end up with systems that are of equal business value, much more (cheaply) maintainable, faster, and a tenth the size of the existing codebase. There are immediate wins in test coverage, quality, system performance (reduced resource requirements), and general maintainability - the bar for successfully working with the system without making mistakes or introducing bugs is much lower.
Overestimation of developer abilities - simpler systems are safer to maintain. Much architecture happens with the assumption that the developers maintaining the system work with complete knowledge of the intended architecture and how the system is supposed to work. On any production system of any level of complexity, that just isn’t true. Look around you, think back on the mistakes made on the systems you work on. Many of those were made because of incomplete knowledge of how the system was supposed to be maintained. On a system large enough to require multiple teams or development sites, the assumption of complete knowledge is dangerous. New developers and development teams will be brought on to work on it; training, review and oversight will be incomplete. Mistakes will be made. The more complex the system, the more those mistakes will occur and be compounded.
My basic rule of thumb is if a subsystem cannot be understood (both code and design intent) by an average developer in a couple of hours, then the initial architects and developers have failed. Obviously there are special cases outside of standard IS development - scientific applications, embedded systems, etc. where the core is necessarily complex. Lets face it though - most of us do not work on these most of the time.
Be happy with simplicity. Resist the urge to add complexity just because the simplicity of the basic problem offends your ego. Harsh but true. How many frameworks and baroque systems have been created just because the authors needed to write a platform rather than the couple of hundred lines of code that actually solved the problem. Take pride in minimal, simple solutions to problems - there is elegance there.
The same goes for continual rearchitecting of solutions. If there is an existing, simple, maintainable solution to the business problem, leave it alone. Don’t fall for the need to be continually applying the newest shiny techniques just to appear cool, or provide justification for coming into work in the morning. If the architecture is done, there’s no need to keep messing with it. Find a new project to satisfy your creative impulses, or maybe get your hands dirty and help out with the development between architecture tasks. If (some, not all to be sure) architects spent more time dealing with the results of their decisions at the coal face, there would be architecture that would be a lot easier to code.
Shared at https://www.linkedin.com/pulse/simplicity-code-donal-stewart