Ok, I understand that this title seems like an outlandish and irrational proposition, especially if you’re a ‘dollars person’. So allow me to rationalise this caveat the statement with some strategies for reuse, and explain why I think this idea is an important one to consider.
A year ago, Marie Kondo sparked a decluttering phenomenon with the ‘KonMari Method’; a system of simplifying and organising your home, category by category, and removing everything that does not bring joy. For some, it was life-changing. Link to article
Reading this article got me thinking about software clutter. As a developer, I am constantly being asked to help solve business problems and find that I am constrained by mainly two things:
- Software is maintainable and serviceable: Providing solutions that meet the requirements for maintainability and serviceability and are approachable enough for support staff and future project developers. The very purpose of software is to communicate human concepts to a machine and to the people servicing those machines and the coded concepts.
- Software integrates with existing infrastructure and components: Providing software that can easily integrate with existing infrastructure and components. Again, to use the analogy of plumbing, the pipe work needs to connect with main water supplies. The system should handle the pressure ranges in the main supply and any waste should meet the requirements of grey water and sewerage systems.
The sorts of things that a plumber integrates with change once in a lifetime. Maybe twice which is . great. But software is different, and change is not just certain; it is imminent and regular. New innovations that promise untold efficiencies regularly present to IT Managers in a way that either could be compatible or incompatible with existing applications and that, over time, have become important parts of the corporate infrastructure. Your upcoming projects and innovations are constrained by the things that already exist. They need to work together and the investment that has been put into these existing applications needs to be utilised to justify their costs.
But what happens when the cost of maintaining software exceeds the value that such software proposes? What happens when someone crunches the numbers on the opportunity cost incurred to a new innovation that is constrained by the existing applications? What is the economics of a software asset? I have spoken to colleagues regularly in the past, about the idea of software having a critical mass. When a unit of software exceeds a certain size, the business cost of change to it, be it that such a cost is incurred via regression testing, development or project management, exceeds the business value of the change, that change can no longer be justified. Critical mass is variable and the variations depend on the quality of the code and the architecture under which that code was written.
When a piece of software has exceeded critical mass, it becomes a burden to the organisation and needs to be replaced. This is often documented as Technical Debt, although what constitutes Technical Debt is a topic for another occasion. It becomes unviable for the application support team to maintain, and the manager of that team will come knocking. It becomes something where a project can’t justify the business value of the change against its cost.
So rather than react to that knock on the door, or leave your architects, developers and project managers with an unnecessary problem, why not throw it out before it gets too big? The article that has inspired this blog, does not present such a new idea. We all know what spring-cleaning means. Could rewriting an application offer us a similar benefit? I think that the main reason why the title of this blog is so absurd is that we know we should make the most of our prior investments. Why throw something out if we have a use for it? To answer this question, we need to weigh up the value of its use against the cost of its maintenance.
The idea that money be invested in something like software (or plumbing) is that it offers an immediate gain and hopefully can be reused to achieve a further gain down the road. Let’s consider reuse. If I have installed pipes to service the bathroom, then a few years from now, when I decide to invest in a dishwasher, I can reuse the investment that I had already made. When determining requirements for the plumbing to service the bathroom, it is likely I already anticipated reusing the infrastructure for something like a dishwasher, should the need arise. If I was smart, this was factored into the original investment decisions, but reuse incurs regression.
Micro-services and dependencies
The more dependencies on a unit of functionality, the more regression testing is required when change happens. In order to minimise the regression of a reused component in software, you can either limit the functionality of the component, making it smaller and therefore less subjected to change or you can limit the number of things that depend on it. Most of us would rather maximise the reuse and therefore we make things smaller.
This is the idea behind micro-services. So, with this in mind, let me return to the seemingly absurd proposition that we should throw out our applications and write them again. If we separate out the micro-services into the smallest units that we can manage, we effectively reduce the likelihood that they change. If we then wrap them in dependency management tools, we can bring them back into a new application and also understand, in fine-grained terms, the things that depend on them.
Applications, themselves are typically a combination of user interface code and integration code, although there are many applications that don’t have a UI. Essentially, they are boundary controllers (to use the old Domain Model concepts).
Applications should not actually contain any real business logic. That logic should be delegated to specialised functions and services that, under my proposition, should be the smallest composable units that they can practicably be, with appropriate APIs that match the application languages and frameworks of the time.
Applications are just orchestration code for business logic and not themselves, business logic code. As such, they should be written using the most lightweight tools available that meets non-functional requirements like maintainability, serviceability, scale and performance. The time to rewrite actual application code should be small and predictable and the application code (not necessarily the micro-services) should be coded in a non-complex programming language to minimise project risk and maximise the resourcing potential for the code that is most often being worked on.
So, when I say ‘Rewrite your applications every 3 months’
I guess that I am being a little cheeky. I really mean that you should rewrite your orchestration logic and tighten the screws on small business logic units. The environment that application code runs in changes all the time anyway, so rather than eventually having to run an upgrade project as a reaction to this, just to rewrite the code regularly.
Make it a practice and a process within your organisation and it will come within a predictable time and cost, without incurring so many constraints to business innovation. Such a practice would deliver business agility and make your organisation an exciting place for people to work. These are two very positive business outcomes, particularly for those who depend on innovation in the market.
Like spring cleaning, a ceremonial rewrite of an application gives developers an opportunity to cull what is extraneous and this leads to better architecture and less aggregate code. This means less cost and more dynamic systems ready to shift for a cost saving or market opportunity. Anything that is kept is separated out into a small unit of functionality, independently tested and optimised and brought into the new application as dependency.
Typically, the ‘new’ application will be written in a similar language and for a similar runtime as its predecessor. Therefore, it is possible that the dependencies could be packaged and deployed together as a compile time binding, but this should not be an assumption. It is perfectly reasonable that the new application will be written in a different language or run on a different platform to take advantage of a new innovation, integration or run time opportunity. The dependencies should not dictate this, or the new application will remain constrained by the technology they were built in.
Instead, consider whether these micro-services could be wrapped in a ReSTful HTTP interface or a listener bound to a queue or topic instead. Any micro-service written in a language or for a platform that can’t support such standard integrations is probably a technical debt to its owner and should be rewritten in a language that can. Of course, such a rewrite could be done in a small and predictable timeframe if we have packaged the code in the smallest composable units.
So, in summary, if we strive to throw away our application code regularly and use the spring clean to put aside the things that we want to reuse, then we can stay up to date with the most modern trends in technology and keep our business logic in small reusable components that are thoroughly tested and isolated from regular change. This allows us to take advantage of innovations whilst making use of the logic that we are most invested in.
Why not ask your developers how long it would take to rewrite an application. If you get a big number back, it means that you are technically constrained as a business. It is probably very important that you do it as soon as possible. That way you can do it quickly, predictably and cost effectively when you really need to take advantage of a market or cost saving opportunity that arises. You could run a long transition project whenever this happens…or, you could make a practice of rewriting your software applications every 3 months!
Written by Diversus Senior Technical Consultant