In the world of software development, we often find ourselves grappling with the complexity of our codebases, much like urban planners navigating the intricate landscapes of cities. The following comparison isn’t just a whimsical analogy; it could offer profound insights into how we can improve our software systems by drawing parallels with urban development.
“We build our computer [systems] the way we build our cities: over time, without a plan, on top of ruins.” – Ellen Ullman
Old Cities and Legacy Code
Think about walking through the old streets of Rome or London. Each part of the city tells a story from the past. For example, under the Shard in London, you can find a Roman mosaic, a piece of history showing how the city used to be.
Legacy code is like these old cities. It’s the old programming code in software that has been worked on by many different developers over the years. Just like ancient cities, this code has been built up in layers, with each change adding more complexity. And just as these cities developed over time without a clear plan, legacy code often becomes a mix of many quick fixes and patches, leading to a messy and complicated structure.
The Unplanned Growth
When cities grow without a plan, it can cause traffic jams, inefficiencies, and a lack of organization. Buildings and roads end up randomly placed, leading to congestion and infrastructure problems.
In software, this kind of unplanned growth happens too. It’s called technical debt, where quick fixes and shortcuts build up over time, making the code harder to manage and expand. Scalability refers to how well software can handle growth. Just as a poorly planned city struggles to accommodate more people and traffic, a codebase with lots of technical debt struggles to handle new features and more users.
Dead Code and Abandoned Buildings
Just like abandoned buildings can harm a neighbourhood’s reputation, dead code can have a similar impact on a software project. Abandoned buildings often become neglected eyesores, attracting vandalism and contributing to a decline in the area’s appeal.
Similarly, in software, dead code refers to unused or obsolete code that remains in the codebase. This unused code clutters the system, making it more difficult to understand and maintain. It can confuse developers, leading to wasted time and effort, which lowers the overall quality of the codebase.
Regularly identifying and removing dead code is essential for keeping a software project healthy and efficient, much like efforts to renovate and revitalize neglected urban areas.
The Speed of Urban Development
To illustrate how quickly cities can evolve, consider the former photo taken during a school geography field trip in the late 1990s. The picture captures One Canada Square tower in London, at the time the tallest building in the UK. A title it held for many years until surpassed by the Shard in 2012. The tower stands in what was once a rural area, marking one of the initial constructions under a new regeneration initiative. Today, it is surrounded by many other skyscrapers, highlighting the city’s remarkable transformation and expansion within a relatively brief timeframe.
Learning from Urban Planning
Urban planning provides valuable lessons that can be applied to software development to create better, more sustainable environments for both users and developers:
- Modular Design (microservices): Cities benefit from zoning laws that separate residential, commercial, and industrial areas, which helps in organizing and managing different aspects of urban life. Similarly, in software development, modular design involves breaking down a system into distinct, manageable modules. This approach reduces complexity and makes maintenance easier by focusing on individual components rather than the entire system at once.
- Green Spaces: Cities incorporate parks and green spaces to improve quality of life and prevent overcrowding. In software development, this concept translates to regular refactoring and cleanup of the codebase. These “green spaces” in code prevent the accumulation of technical debt—unused or obsolete code—ensuring the system remains efficient and easy to work with over time.
- Infrastructure Planning: Well-planned cities have robust infrastructure, such as roads, public transport, and utilities, that support daily activities and growth. Similarly, a well-planned codebase includes clear documentation, consistent coding standards, and automated testing. These elements ensure the software is reliable, scalable, and easy to maintain.
In summary, applying principles from urban planning—such as modular design, regular maintenance (like green spaces), and robust infrastructure planning—to software development can lead to more efficient, scalable, and sustainable software systems.
Enhancing Codebases with Urban Principles
We can draw inspiration from what makes a great city to enhance our codebases:
- Accessibility and Inclusivity: Just as cities aim to be accessible to all residents, our codebases should be accessible to all developers, with clear, understandable code and thorough documentation.
- Sustainability: Sustainable cities focus on long-term well-being. In software, this means prioritizing maintainable and scalable solutions over quick fixes, investing time in building a robust architecture.
- Community Engagement: Cities thrive when residents are engaged. Similarly, fostering a strong developer community around a codebase, where knowledge is shared and collaboration is encouraged, leads to a healthier codebase.
Quality of Life in Codebases vs. Cities
The quality of life in a city significantly affects its residents’ happiness and productivity. Similarly, for developers working on a codebase, a well-maintained and thoughtfully designed environment can have profound effects. Here’s how some of these parallels unfold:
Environmental:
- City: Clean air, green spaces, and sustainable practices contribute to a healthier living environment.
- Codebase: A well-maintained codebase reduces technical debt and inefficiencies, promoting a cleaner and more efficient software environment.
Social:
- City: Community engagement, safety, and inclusivity foster a sense of belonging and well-being among residents.
- Codebase: A well-designed codebase promotes collaboration, knowledge sharing, and a positive team culture among developers.
Economic:
- City: Job opportunities, cost of living, and infrastructure impact residents’ economic stability.
- Codebase: Clear requirements, attitude to code quality, attitude to technical debt, shared vision, trust, dedication to automating processes and awareness of context switching.
In both urban and software environments, ensuring high quality of life enhances overall happiness, productivity, and satisfaction among residents and developers alike.
The Urban Planner’s Oath
As we conclude, let us reflect on the Urban Planner’s Oath and adapt it to software development:
- Respect for Legacy: “I honor the wisdom of those who came before me. With humility, I stand on that which they have built.” Developers should respect the work of previous developers and be sure they did the best they could with that they had.
- Service to the Present: “I serve those who live here today; their actions shape my actions. My vision must dance with theirs.” Our code should serve current users and developers, accommodating their needs and facilitating their work.
- Responsibility to the Future: “We work for those who come tomorrow. May we decrease their admiration and inspire the best within them.” Our work should pave the way for future developers, making their tasks easier and inspiring them.
Conclusion
By viewing our codebases through the lens of urban development, we could gain valuable insights into creating more sustainable, maintainable, and enjoyable software systems. Just as great cities are built with foresight, respect, and community spirit, so too can our codebases be crafted to stand the test of time, serving generations of developers to come.
Reference: Naomi Gotts, “We Built This City: The Geographies of Software Development,” http://NaomiGotts.co.uk.