#📚reference In the contexts of [[software development]] and [[solution architecture]], maintainability is one of the [[product specification#Requirements Document|non-functional requirements]], which refers to the ease of supporting the software: the ability to modify, enhance, debug, or repair the system over time. According to many experts, poor maintainability is one of the leading technical causes of project failures. Being hard to measure, easy to screw up, and non-obvious during the early project stages, maintainability becomes crucial as the product grows. It is key in determining the ability to respond to the expanded market / user demands, along with the potential performance and scalability challenges. --- ## Aspects The maintainability considerations are referred to the following aspects. ### Complexity Software systems often grow in complexity over time due to changing requirements, new features, and technological advancements. Without proper maintenance, this complexity can become overwhelming and hinder further development. Considering the non-linear dependency of the cost over complexity growth, your project can easily reach the point when all the IT-related costs are addressed on bug fixing and support, so new features can't be introduced. Things get more grammatical when we realise that adding more developers/teams to the project probably won't help without a fundamental mindset shift: communication overhead and cross-blockers will push the effectiveness down and, in the end, will increase the complexity of the software system. ### Legacy systems Many organizations rely on legacy systems that were developed years or even decades ago. These systems often lack proper documentation and may be difficult to maintain without careful attention to maintainability. It's not uncommon that software systems are not able to update a codebase to work on the new operating system versions, while new features technologies are available only on updated OS versions. Non-testable, poorly documented codebases are scary to touch, especially when they are becoming the core of the business. In time they started to be treated as a "Black Box", which is a few steps before the dead end. ### Team turnover As developers leave or join a project, knowledge transfer becomes essential. Maintainable code with clear documentation and well-defined coding standards makes it easier for new team members to onboard and contribute effectively. Clear decision logs allow users to keep a motivated change thread, allowing them to continue the vision defined by the predecessors, as well as have a background for grounded re-considerations. ### Interdependencies Software systems are rarely isolated entities; they often interact with other systems, libraries, or APIs. Changes made to one part of a system can have ripple effects throughout the entire ecosystem, highlighting the importance of maintainability in managing these interdependencies. Well-boundary components with straightforward contracts, proper versioning, and effective release strategies are the keys to managing tens of different subsystems in a controlled way. --- ## Tactics Some of the core approaches for keeping a system maintainable over time intersect heavily with the motivation behind [[dev excellence]] and [[clean code]]. Additionally, the following tactics should be kept in mind. ### Modular design Decompose the system into smaller, cohesive modules with well-defined responsibilities. This promotes code reusability, simplifies testing, and isolates changes, making the system easier to maintain. ### Clear documentation Document code, architecture, design decisions, and APIs comprehensively to aid understanding and future maintenance efforts. ### Adherence to coding standards Enforce consistent coding conventions and best practices to improve readability and maintainability across the codebase. ### Automated testing Implement robust unit tests, integration tests, and regression tests to detect and prevent regressions during maintenance activities. [[Testing piramid]] might be a good reference point for what kind of test distribution you want in your system. ### Refactoring Regularly refactor code to eliminate duplication, improve readability, and enhance maintainability without changing external behaviour. Using tools like Sonar Cube and static code analysis assistants like Re-Sharper and others helps you find the places for improvements and make your refactoring easier. ### Version control Utilises version control systems effectively to track changes, collaborate with team members, and roll back modifications if necessary. A correctly picked merging strategy that follows your company scale and workflow will emphasise the ease of changes and reduce the risks and fear of losing the code. ### Continuous integration and deployment (CI/CD) Automate build, test, and deployment processes to streamline maintenance workflows and ensure the reliability of software updates. Suitable environments with a quick feedback loop allow you to find the defects earlier in the release cycle and prevent sneaking into production. Remember, fixing a bug on the production will easily cost you x10, compared to the bug found and fixed before the release. --- ## Balance is key Considering modern time-to-market priorities, it's often not reasonable to build a system following all the best practices from day one of development (unless the requirements analysis indicates the opposite). With Agile in mind, we want to balance implementing the new features and maintainability-oriented activities to stay competitive and meet the investors' and other stakeholders' functional expectations. Ensuring such a balance - is one of the crucial responsibilities of [[technical leadership]]. Wavering between preventive measures, reactive maintenance, and keeping track of the [[tech debt]] and failures\reports rates, the tech leader keeps the maintenance costs in the effective zone while ensuring that the delivery capacity of new features meets expectations. ![[maintenance cost.png|600]] --- <font style="color: #F86759">Contributors:</font> *[[Eugene]]* <font style="color: #F86759">Last edited:</font> *2024-02-27*