By James Wilt, Distinguished Architect
Apology
This was originally titled, “Disposable is the new Reusable”, however, experience has taught such titles rarely are read beyond well, the title! Case in point is Grey Young’s “The Art of Destroying Software” which is unfortunate as it stands as a strong background/basis for this concept.
Some History
In 1986, William Wong as part of the NIST Computer Science and Technology group produced the National Bureau of Standards Special Publication 500-142, A Management Overview of Software Reuse. The 1994 book, Design Patterns: Elements of Reusable Object-Oriented Software, authors Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (a.k.a. the gang of four) re-introduced the concept of reusability through object inheritance. It has since been and continues today to be promoted via shared services (e.g., the Enterprise Service Bus).
Fast forward a couple decades past its origination and the Enterprise has locked into reuse as a strong justification for many if not most software design/architectural decisions under the impetuous that it will improve software quality, lower maintenance burden, increase productivity, and reduce software risks.
Technical Problems with Reuse
Where has this Enterprise adoption of reuse taken us? We’ve become technology pack-rats with too large a percentage of our portfolios left in extended warranty or completely out-of warranty.
Any initial financial benefit has been long lost to exorbitant integration costs required to make our “reusable” platforms talk to each other. Our market agility and innovation has been all but eliminated. We develop from a stance of fear we’ll break something critical in production.
- Reuse trends toward additive-only/bolt-on features resulting in Swiss army-knife services often constrained by imposed backward-compatibility requirements that actually can prevent bugs from being fixed due to downstream dependencies.
- As deep dependencies are formed, development cycle time & cost actually increase, depleting key goals of reuse.
- Bloat. Monoliths start small and only grow over time. In a 10-year span, the Java JRE (versions 1 to 6) grew from 212 classes to 3777 classes. No engineer will ever know them all. Bloat has forced engineers to abandon any hope of understanding the large monoliths they must support (even when they created them).
- As logic is reused across the enterprise, shared services become a common repository forcing them to become context & state aware where multiple versions of logic & business rules must be accounted for directly in code. Modification for one context may negatively impact others (see bloat above).
The Solution
- Replace reusable in our Enterprise vocabulary & practices with replaceable enabling teams to build systems where the code base can move freely to support the increasing pace of business demands and technology innovations.
- Replaceable code diminishes boxing ourselves in unintentionally and promotes great agility. Whether it’s a refactor or a rewrite, it’s no more than a week per component (Greg Young’s rule of thumb below).
An enterprise with a significant legacy base, however, cannot simply flip a switch to get there. Even with Martin Fowler’s Strangler-Fig pattern and the adoption of stateless microservices, enterprises struggle to decompose and separate tightly coupled monoliths as they are generally maintained by siloed engineering teams – each responsible for a subset of the monolith. This type of transformation takes years.
Enterprises should instead lay down guidance that promotes replaceable best practices for everything net-new and build development muscle using this concept first. Once established, teams can then apply these concepts to legacy systems.
What Means Replaceable?
Tenants for replaceable code include:
- Fully isolated Microservices with well defined interfaces (e.g., API & JSON payload are independent of the code underneath), loose coupling, and stateless when possible.
- Limited dependencies.
- Code that can be easily and immediately swapped with another code base while preserving interfaces and behavior.
- Greg Young’s rule of thumb: The time it takes to do a full write or a full rewrite for part of the software (e.g., microservice) should not exceed one week.
Where Reuse Remains
- Patterns are among and should remain the most reusable components of the entire ecosystem.
- API reuse is implied – anyone can use an API once it’s published into the ecosystem. Versioning should be leveraged to protect contract and payload formats for the time-bound duration that version remains supported.
References
- A management overview of software reuse (nist.gov)
- (PDF) Searching the library and asking the peers: Learning to use Java APIs on demand (researchgate.net)
- Why Software Reuse has Failed and How to Make It Work for You (vanderbilt.edu)
- Writing Disposable Code, Not Reusable Code | Björn Wilmsmann (bjoernkw.com)
- Write code that is easy to delete, not easy to extend — programming is terrible
- The growth of Java SDK API classes and interfaces Given the sheer… | Download Scientific Diagram (researchgate.net)
- Source Code Reuse | Shaping Software
- Software Engineering: Best Practices for Reusing in Software Development | by Anh Dang | Level Up Coding (gitconnected.com) Modern Software Over-Engineering Mistakes | by RDX | Medium
- The Art of Destroying Software
- Martin Fowler Microservices – a definition of this new architectural term
- Martin Fowler Strangler Fig Application