Now Reading: How to Design (and Not Design) Software: A Synthesis from Decades of Experience – John Ousterhout

Loading

How to Design (and Not Design) Software: A Synthesis from Decades of Experience – John Ousterhout

John Ousterhout, Professor of Computer Science at Stanford University gave a talk at Google about the Philosophy of Software Design. I found that talk life-changing as a programmer and I often recall his references in my daily coding life. In today’s article, I tried to summarise the “Take away from his talk”.

IndexTopicPage/Section
1Introduction to Software DesignSection 1
2Problem Decomposition in Computer ScienceSection 2
3Can Software Design Be Taught?Section 3
4Key Design PrinciplesSection 4
5Classes Should Be DeepSection 4.1
6Avoid Over-Fragmentation (Classitis)Section 4.2
7Define Errors Out of ExistenceSection 4.3
8Strategic vs. Tactical ProgrammingSection 5
9Real-World Constraints and Software DesignSection 6
10The Facebook Dilemma: Can Bad Code Succeed?Section 7
11Future of Software DesignSection 8
12ConclusionSection 9

In a compelling talk at a Google event, Professor John Ousterhout of Stanford University delivered an insightful presentation on software design. With decades of experience in academia and industry— including founding companies like Electric Cloud and contributing to influential systems such as the Sprite Operating System and Raft—he distilled lessons learned about both the right and wrong ways to approach software development.

The Problem with Software Design

Ousterhout opened with a powerful observation: despite 80 years of programming, software design remains a “black art,” with little consensus on what constitutes good design. While we discuss testing, processes, and tools, the fundamental act of designing software is rarely taught or even discussed. This gap in the education and industry practice is one he seeks to fill through a course he created at Stanford and his book, A Philosophy of Software Design.

The Most Important Concept in Computer Science: Problem Decomposition

Ousterhout argued that problem decomposition—the ability to break complex systems into manageable parts—is central to all computer science disciplines. However, this key skill is rarely emphasized in educational curricula. He also pointed out that there is a well-known phenomenon where some programmers are dramatically more productive (often called “10x programmers”), yet few attempt to teach what differentiates them. His course is an attempt to systematically address these gaps.

Can Software Design Be Taught?

Ousterhout believes that software design can be taught, but there are significant challenges. Many faculty members lack the necessary experience to teach design, having only written minimal amounts of code themselves. By contrast, Ousterhout has written over 300,000 lines of code during his career, giving him the practical experience needed to teach real-world software design. His course at Stanford, CS193P, approaches coding like high school English: through iterative design, review, and revision. Students build systems, receive feedback, and improve their designs through multiple iterations.

Key Design Principles

Ousterhout shared several of the core design principles he emphasizes in his course and book. Here are some of the key takeaways:

  1. Classes Should Be Deep: A well-designed class provides a lot of functionality through a simple interface, maximizing benefits while minimizing complexity. In contrast, “shallow” classes offer little functionality or require overly complex interfaces, adding more complexity than they hide.
  2. Avoid Over-Fragmentation: A common mistake is creating too many tiny classes, a practice Ousterhout called “classitis.” This practice is prevalent in languages like Java, where even basic tasks often require creating multiple objects, which increases complexity unnecessarily.
  3. Define Errors Out of Existence: One of Ousterhout’s more radical principles is the idea of eliminating errors rather than handling them with exceptions. For example, he suggested that operations like deleting a non-existent file or extracting a substring outside of a string’s range should not raise exceptions, but rather handle the situation gracefully, avoiding the need for complex error-handling code.

Strategic vs. Tactical Programming

A major theme of the talk was the difference between tactical and strategic approaches to software development. Tactical programming focuses on getting the system working quickly, often at the cost of clean design. This approach leads to systems that quickly become overwhelmed by complexity. Ousterhout pointed out the problem with “tactical tornadoes,” programmers who churn out large amounts of poorly designed code that only works temporarily, but wreak havoc in the long term.

By contrast, strategic programming focuses on building a system with clean design principles, ensuring that the software is maintainable and extendable in the future. This approach may take longer upfront, but it results in faster, more reliable development down the line.

Real-World Constraints and Software Design

Ousterhout acknowledged that real-world software development is often constrained by tight deadlines, experimentation needs, and imperfect tools. However, he argued that even under pressure, it’s essential to invest in good design. He estimated that investing around 10-20% more time into strategic design today would yield a payoff in six to 12 months, as the codebase becomes easier to maintain and extend.

The Facebook Dilemma: Can Bad Code Succeed?

Ousterhout highlighted Facebook as an example of a company that succeeded despite using a very tactical approach, with its early motto being “move fast and break things.” However, he argued that while Facebook became successful, their codebase turned into a “notorious mess,” and the company eventually had to shift its focus to building “solid infrastructure.” Ousterhout contrasted this with companies like Google and VMware, which he believes took a more strategic approach to design from the start, resulting in better long-term outcomes.

The Future of Software Design

Ousterhout concluded with a call for greater emphasis on software design within the programming community. He hopes that through his course and book, he can help foster a broader discussion around the principles of good design. Ultimately, his goal is to create a set of widely agreed-upon design principles that can be taught and implemented across the industry.

Final Thoughts

John Ousterhout’s talk provided a wealth of insights into the philosophy of software design. His emphasis on deep classes, error minimization, and strategic thinking presents a strong argument for why design matters more than most developers realize. While tactical programming might seem appealing for meeting immediate deadlines, Ousterhout convincingly demonstrated that investing in design pays off in the long run by reducing complexity and improving maintainability. As more developers and organizations adopt these principles, the future of software design could become far less of a “black art” and more of a well-understood science.

0 People voted this article. 0 Upvotes - 0 Downvotes.
svg
Quick Navigation
  • 01

    How to Design (and Not Design) Software: A Synthesis from Decades of Experience – John Ousterhout