Evolution over Revolution:

A Pragmatic Approach for Software Development

Imagine . . .

A highly anticipated game turns out to be a disappointment, leading to the downfall of a gaming company.


A team caught up in the frustration of maintenance undergoes a reckless revolution, resulting in shattered deadlines and frustrated stakeholders.

In application development, I prefer evolution over revolution. Downside: Less recognition. Upside: Not getting shot

In the fast-paced world of software development, it's easy to get swept away by the allure of revolutionary ideas. We're often enticed by the promise of quick solutions and groundbreaking innovations that promise software that is better, faster and easier to write. However, it's essential to take a step back and adopt a pragmatic approach. We should focus on the power of evolutionary progress and the long-term benefits it brings. With this article I hope to explore the merits of an evolutionary approach, emphasizing incremental improvements and learning from past experiences. I will explore key themes such as the pitfalls of chasing revolutionary changes, the importance of building on existing knowledge, and practical strategies for implementing evolutionary progress in software projects. Through a series of case studies, including the Duke Nukem Forever saga and the Betamax versus VHS format war, I hope to illustrate how an evolutionary approach can lead to more sustainable and successful outcomes.

Being pragmatic in software development means avoiding reactionary impulses and carefully considering the potential consequences of our decisions. It means recognizing that not every shiny new technology is worth pursuing, and true success often lies in steady, incremental improvements rather than radical overhauls.

The Illusion of Revolution

While fighting legacy code, it is easy to get caught up in the allure of revolutionary ideas. The promise of a complete overhaul, a fresh start, and a chance to make a significant impact can be tempting. However, let's consider the consequences.

Revolutionary endeavors often carry an inherent risk of disruption, chaos, and unintended consequences. They can lead to shattered deadlines, frustrated stakeholders, and a loss of productivity. While a successful revolution may bring recognition to those involved, it can also introduce unnecessary risks, resembling a bull in a china shop.

The Book That Made Us Think Twice

Enter the popular book "If it Ain't Broke...Break It!" by Robert J. Kriegel Ph.D. and Louis Palter. This thought-provoking book challenges the notion of evolution and encourages us to consider alternatives. Kriegel argues that sometimes, to evolve, we must be willing to break the existing mold. This is an approach to battle stagnation and complacency and to encourage innovation and growth. It's a call to action to break the status quo and challenge the way things are done. It's a call to break things.

However, we must approach the idea of breaking with caution. While breaking things might be necessary at times, it should not be taken as a carte blanche to embark on a reckless revolution. Instead, it should be viewed as a call to carefully consider when and where evolution needs a gentle nudge. Here are some key takeaways from the book.

Embrace innovation and change
The book emphasizes the importance of pushing boundaries, challenging existing norms, and being open to new ideas, even if it means breaking something that seems to be working fine.
Avoid complacency
The book highlights the dangers of complacency and the comfort of maintaining the status quo. It encourages readers to continuously seek improvement and innovation to stay ahead in a rapidly changing world.
Emphasize the power of disruption
Disrupting existing systems, processes, or products can lead to breakthroughs and create new opportunities for growth and success.
Encourage calculated risk-taking
Taking calculated risks encourages readers to step outside their comfort zones and challenge the existing order to drive progress.
Learn from failure
The importance of learning from failures and setbacks, emphasizing that even when something breaks, valuable lessons can be derived from the experience, leading to future success.
Pragmatic Evolution

As software developers, we should be building upon existing foundations and embracing an evolutionary mindset. By taking small, deliberate steps forward, we can avoid the pitfalls of revolution while steadily improving our codebases.

Pragmatic evolution allows us to learn from our mistakes, iterate on previous successes, and adapt to changing requirements. It prioritizes stability, maintainability, and a seamless user experience. It may not make headlines or attract immediate recognition, but its long-term benefits are undeniable.

Evolutionary progress emphasizes steady improvement, learning from experience, and adapting to changing requirements. It recognizes that software development is an iterative process, where ideas are refined over time based on user feedback and market demands. This approach allows us to build upon existing foundations, leverage proven technologies, and avoid unnecessary disruption.

Forcing Evolution

While evolution typically occurs naturally over time, there are instances when we must force the pace. Sometimes, external factors necessitate a more rapid transformation. However, this forced evolution should be undertaken thoughtfully and with a clear understanding of the risks involved.

When forcing evolution, it's crucial to balance the need for change with the need for stability. This delicate equilibrium ensures that our applications remain robust and reliable, even amidst significant shifts. By carefully planning and executing the necessary changes, we can navigate the turbulent waters of rapid evolution without capsizing our projects.

Forced evolution is exemplified by the campaign of building the plane while flying it by my former employer Electronic Data Systems(EDS). There is a great write-up on the EDS commercial by Duncan Macleod on his blog POSTWIKI called EDS Airplane

Learning from History

History is full of examples where an idea that evolved defeated the failed revolution. These instances demonstrate the power of embracing an evolutionary approach and highlight the potential for long-term success. Let's explore a couple of notable examples

Duke Nukemn Forever(DNF): The Perils of Perfectionism

The story of Duke Nukem Forever's tumultuous development is a cautionary tale of the perils of revolutionary thinking and the importance of embracing evolution in software development. Scott Miller, the founder of Apogee, the company behind 3D Realms, shared his insights into the project's troubled history. Let's take a closer look and draw some valuable lessons from this rollercoaster ride.

DNF was a highly anticipated game but ended up being a disappointment. When finally released, the gameplay fell far short of the brilliant trailer that had hyped it up. The project became a money pit, contributing to the downfall of 3D Realms and forcing the company to be sold. So, what went wrong?

Rebooting with New Technology
As the game's development lagged, new 3D technology emerged. Rather than leveraging existing progress, the project repeatedly rebooted to incorporate the latest tech, causing significant delays and prolonging the agony.
Lack of a Development Roadmap
Surprisingly, the project lacked a clear development roadmap. This absence of a guiding plan meant that the project was adlibbed, leading to haphazard decision-making and potential missteps along the way.
One of the key issues highlighted by Scott Miller was the chronic understaffing of the DNF project. Being understaffed by at least 50% meant that the development team faced an uphill battle, struggling to keep up with the project's demands.

It is clear that trying to find the perfect solution and constantly rebooting led to a missed opportunity and a failed project. My key takeaway is that sometimes, we must be willing to accept incremental improvements and avoid the temptation to pursue perfection.

Betamax vs. VHS: The Video Cassette Format War

In the 1970s and 1980s, the video cassette format war unfolded, with Sony's Betamax and JVC's VHS vying for dominance. Betamax was the first mover, boasting superior video quality and technical capabilities. However, JVC took an evolutionary approach with VHS, focusing on longer recording times, lower costs, and licensing flexibility. Despite Betamax's initial technical superiority, VHS eventually emerged as the dominant format.

VHS's wider availability, longer recording capabilities, and lower prices won over consumers and led to its widespread adoption. This example demonstrates that evolutionary advancements aligned with market demands can outperform revolutionary innovations.

A Personal Example

As a young developer, I once had an innovative idea for a new way of viewing summary data. Excited about this revolutionary concept, I dedicated an entire night to designing and implementing it. Although exhausted, I felt proud of my achievement and eagerly presented a screenshot of the new interface to the customer.

However, the next morning brought an unexpected turn of events. Instead of a celebration, I was met with a frustrated customer who raised concerns about training the staff on this revolutionary approach. They questioned how we would seamlessly integrate the new design and expressed worries about the months of work already invested in the rest of the system.

Reflecting on this experience, I now understand the importance of embracing evolution over revolution in software development. While my intentions were good and the idea seemed groundbreaking, I failed to consider the practical implications and potential disruptions that such a revolutionary change would bring.

Following this incident and taking a pragmatic approach allowed me to introduce incremental improvements and build upon the existing work that we had already completed. By gradually evolving the system, we avoided the need to discard months of work and the challenges of training staff on a completely new way of working.

In hindsight, I realize that thoughtful and measured evolution was the more effective approach. It allowed us to leverage the foundation we had already established and make iterative enhancements based on user feedback and evolving requirements. This pragmatic evolution resulted in a smoother transition and ensured that the customer's concerns were adequately addressed.

These examples illustrate that while being a revolutionary disruptor can have its advantages, an evolutionary approach allows for continuous improvement based on market feedback and user needs. By adapting and refining ideas over time, developers can achieve greater success and surpass the initial revolutionary offerings.

By focusing on evolutionary progress, we can make informed decisions, learn from past mistakes, and create software solutions that stand the test of time. It's about being pragmatic, understanding the needs of our users, and aligning our efforts with their requirements and expectations.

The Pragmatic Approach

Pragmatic Evolution is the best path forward. It acknowledges the value of existing systems, the knowledge accumulated over time, and the stability they provide. By taking a pragmatic approach, we avoid unnecessary disruptions and reduce the likelihood of introducing new issues while addressing existing ones.

Rather than seeking revolution, we embrace incremental improvements. We prioritize maintaining a solid foundation while introducing well-tested and well-documented enhancements. This approach allows us to build upon what works, minimizing risk and maximizing the value delivered to stakeholders.

Maintaining Business Agility

Our applications are not isolated entities but integral components of larger business ecosystems. For production business applications. The need to quickly respond to market conditions demands a different approach — one that embraces evolution without hindering day-to-day operations.

Imagine a scenario where a company's critical business application undergoes a complete revolution, requiring a six-month freeze on updates and enhancements. During this time, market dynamics could shift, customer expectations could change, and competitors could swoop in, capitalizing on the opportunity. By the time the re-architecture is complete, the business might find itself playing catch-up, struggling to regain lost ground.

To avoid such predicaments, we must adopt an evolutionary mindset that allows for incremental changes while maintaining business operations and responsiveness. This approach acknowledges the need for continuous improvement and agility, enabling organizations to adapt to market conditions without sacrificing stability.

Implementing Change in Small Increments

Instead of freezing development for an extended period, focus on rolling out changes in smaller, manageable increments. By breaking down larger transformations into bite-sized pieces, we can introduce enhancements and improvements without disrupting the entire system.

This incremental approach enables businesses to respond to changing market conditions effectively. New features, optimizations, and bug fixes can be prioritized, developed, and released in a controlled manner, ensuring minimal disruption to daily operations. This allows the business to maintain a competitive edge, adapt to customer demands, and seize opportunities as they arise.

Striking a Balance

The key to success lies in striking a balance between evolution and business continuity. While the software team works on architectural improvements behind the scenes, careful consideration must be given to ensure that these changes seamlessly integrate with the existing system.

To achieve this, organizations can adopt strategies such as feature flagging, where new functionalities are developed but not immediately exposed to end-users. This approach allows for thorough testing and verification before gradually rolling out the changes to ensure a smooth transition.

Furthermore, maintaining a strong feedback loop with stakeholders, end-users, and the business itself is essential. By actively seeking input, monitoring user behavior, and continuously refining the software based on real-world feedback, we can ensure that the evolving application meets the evolving needs of the business.

Pragmatic Evolutionary Architecture with Azure Front Door

As we have discussed, executing a complete overhaul of an existing monolithic application can be risky, potentially disrupting business operations and user experience. Thankfully, tools like Azure Front Door and traffic managers offer a pragmatic approach to implementing architectural revolutions gradually, without jeopardizing the business.

Imagine you are part of a development team working on a large-scale monolithic API. You recognize the need for a more scalable and maintainable architecture, and the concept of microservices catches your attention. You realize that migrating the entire application to a microservices architecture is neither practical nor feasible.

This is where Azure Front Door and Traffic Manager come into play. By leveraging powerful routing capabilities, you can gradually introduce new microservices into the system while keeping the existing monolithic API intact. Azure Front Door allows you to control traffic routing at the edge of your application.

You can implement a new microservice alongside the monolithic API, exposing its functionality by rerouting the endpoint from one app server to another. Azure Front Door allows you to define rules and routing logic to split traffic between the monolithic API and the new microservice.

This approach provides several benefits. First and foremost, it mitigates risks by limiting the impact of potential issues in the new microservice. By routing only a fraction of the traffic, you can thoroughly test and validate the behavior and performance of the microservice in a real-world scenario while keeping the rest of the system stable.

This incremental approach empowers you to address any issues and make necessary adjustments iteratively. It facilitates the business to respond to market conditions without disruptions. Providing a single, consistent experience for the consumers of the API while the updated architecture is developed.

Azure Front Door allows you to transform your monolithic application into a more scalable and resilient architecture while minimizing risks and maintaining business continuity. This forced revolution through evolutionary architecture ensures that your development efforts align with the needs and pace of the business, delivering value without impeding its ability to operate effectively.


Evolution vs. Revolution in History

While revolutionary ideas may capture attention and generate short-term excitement, the long-term success of projects lies in the hands of those who embrace gradual change. The pragmatic approach to software development values stability, adaptability, and the lessons of the past. It champions a mindset of continuous improvement and measured progress. By valuing the evolutionary path, we can build resilient applications that stand the test of time. This method not only builds on the solid foundation of existing knowledge and experience but also mitigates the risks associated with drastic changes.

As the popular quote goes, "Insanity is doing the same thing over and over again and expecting different results." Let's not drive ourselves insane with constant revolutions of our software architecture that disrupt the harmony of our ecosystems. Instead, let's embrace the wisdom of evolution and bring about change that is sustainable and builds upon what we already have.

This approach does not mean stagnation. It means learning from the past, leveraging proven techniques, and applying them to meet the demands of the present and future. Strike a balance between innovation and stability, minimizing the chances of ending up with a tangled web of technical debt. By doing so, you will be better equipped to handle the complexities of software development and guide your projects to successful and sustainable outcomes. So, take these insights, apply them in your work, and witness the transformative power of evolution in software development.