The Software
Maintainability Factor

From Legacy Systems to Agile Development and Continuous Deployment
Yiannis Kanellopoulos
CEO and Founder | code4thought
A phenomenon that typically most of the organizations (according to our experience) tend to neglect is that in the fast-paced world of technology, software maintainability remains a critical factor in determining the success and sustainability of digital systems. From the early days of legacy systems to the modern era of Agile Development, Continuous Deployment and DevOps, the journey of software maintainability has been nothing short of transformative.
Working for the past 20 years on software maintainability projects for our clients has given us the opportunity not only to observe this phenomenon but participate actively in its evolution. In this post we will go through how modern development practices have revolutionized the way software is updated and maintained and most importantly, what can be the recommendations to companies looking to adopt them in their everyday operations.
1. The Legacy of “Legacy Systems”: Overcoming Challenges, Embracing Change
In the past, software maintainability was a complex and arduous task, particularly with the prevalence of legacy systems. These systems were often built on technologies that weren’t promoting the writing of maintainable code (e.g. GOTO commands in COBOL), making updates and fixes cumbersome and prone to disruptions. Legacy software was often relied on monolithic architectures, where all functionalities were tightly integrated, making it challenging to isolate and address specific issues. For instance, I vividly remember a client of ours who was complaining that even for changing the text in a label at a Windows form, they had to restart the system and that process could take a couple of hours.
What do we see:
Large corporations struggling with maintaining mainframe systems, where each update requires significant downtime and risked unforeseen issues.
What can be done better:
– Prioritize documentation to understand the existing codebase thoroughly and assess its quality in order to predict the overhead for comprehending the code at hand in order to perform the necessary changes
– Implement version control systems to track changes and facilitate collaboration. This might seem simple, but try doing it in a PL/I system
– Plan for gradual migrations or modernization to reduce risks and ensure continuity
2. The Agile Revolution: Unleashing Agility and Efficiency
The introduction of Agile methodologies brought a significant shift in software development and maintainability bringing the essence of communication into the limelight. Agile’s iterative and incremental approach allowed for more frequent updates, shorter feedback loops and development cycles, and increased adaptability to changing requirements. Agile practices focused on close collaboration between cross-functional teams, prioritizing customer needs, and delivering incremental value with each iteration.
What do we see:
Software development teams either formally or informally adopting Scrum or Kanban methodologies to deliver regular updates and improvements.
What can be done better:
– Foster effective communication and collaboration between development and operations teams
– Embrace automated testing to maintain a balance between agility and quality
– Try not to imitate the waterfall way of working using the Agile practices as a facade
– Encourage feedback loops and continuous improvement to refine the software incrementally.
3. The Emergence of DevOps: A Unified Approach to Success
DevOps emerged as a natural evolution of agile practices, bridging the gap between development and operations. It prioritizes collaboration, automation, and a culture of shared responsibility to streamline the software development and maintenance process. DevOps practices emphasize the automation of repetitive tasks, enabling faster and more reliable software deployments.
What do we see:
Companies implementing DevOps principles to automate infrastructure provisioning, testing, and deployment. Sometimes this tends to be challenging due to legacy technologies, regulations and lack of a culture of collaboration.
What can be done better:
– Create cross-functional teams that include both developers and operations experts
– Utilize infrastructure-as-code (IaC) to ensure consistency and reproducibility of environments
– Implement continuous integration and continuous deployment (CI/CD) pipelines to automate software delivery.
4. Continuous Deployment and Beyond: Empowering Real-Time Innovation
Continuous deployment takes DevOps to the next level, enabling software updates to be automatically deployed to production environments as soon as they are ready. This approach reduces deployment overhead, allowing for faster release cycles and quicker resolution of issues. The ability to quickly respond to customer feedback and market demands becomes a significant  advantage.
What do we see:
Leading tech companies deploying multiple updates to their web applications daily.
What can be done better:
– Prioritize robust automated testing to catch potential issues before they reach production. Keep remembering the exponential costs of fixing a bug in Production (up to 30x times more) compared to the Design, Development or Testing phases.
– Maintain a strong focus on monitoring and observability to detect and resolve issues promptly
– Adopt feature toggling to enable safe, controlled rollouts of new functionality.
5. The Role of Microservices: A Foundation for Scalability and Resilience
Microservices architecture is an integral part of the evolution of software maintainability. This architectural style breaks down complex applications into smaller, loosely coupled services, allowing for independent development, deployment, and scalability. Microservices enable teams to focus on specific functionalities, facilitating faster development and deployment cycles.
What do we see:
Netflix’s transition from a monolithic architecture to microservices, enabling the streaming giant to improve maintainability and introduce new features rapidly has been the showcase for the adoption of Microservices. However, also in this case, Microservices is not a silver-bullet. We have seen teams over-engineering the business requirements and creating an unnecessary plethora of microservices which are difficult to be managed and maintained.
What can be done better:
– Design services around business capabilities to align development with the organization’s needs in a way that keeps the right level of granularity regarding the number of microservices
– Implement strong versioning and backward compatibility practices to avoid disruptions
– Invest in automated testing and monitoring to ensure the reliability of individual services.
6. Continuous Improvement and Learning: Paving the Path to Excellence
Embracing the principles of continuous improvement and learning is essential for companies aiming to excel in software maintainability. It is not a surprise that one of our core values at code4thought is “Keep on learning, innovating and envisioning”. By fostering a culture of innovation, experimentation, and feedback, organizations can continually refine their development processes and identify opportunities for improvement.
What do we see:
Companies that conduct regular retrospectives to analyze project successes and challenges, making data-driven decisions to enhance software maintainability.
What can be done better:
– Encourage open communication and learning from both successes and failures
– Embrace metrics and data-driven insights to assess the effectiveness of maintainability practices
– Provide opportunities for professional development to keep teams up-to-date with industry best practices.
Embracing modern development approaches is crucial for staying ahead of the curve in today’s dynamic digital landscape. By prioritizing human collaboration and communication, automation and continuous improvement, companies can adopt a strategy that ensures their software remains robust, scalable and adaptable in the face of ever-changing user needs and technological advancements.