Overview

1 The path to well-designed software

This chapter sets the stage for designing sustainable Python applications, arguing that well-designed programs are more reliable, flexible, maintainable, easier to test, and often faster to complete. It introduces the book’s focus: teaching object-oriented design principles and industry-proven design patterns, applied in Python but transferable to other OO languages, to help readers move from requirements to robust architectures. Aimed at beginning to intermediate developers who know basic data structures and OOP, the chapter emphasizes a disciplined, iterative path from understanding requirements to delivering an initial viable release and evolving it over time.

The chapter explains why good design matters: sustainable software meets requirements, behaves predictably, performs efficiently, scales with change, supports collaboration, and lowers total cost over its lifespan. It stresses starting by gathering and validating requirements to build the right application, then applying sound techniques to build the application right. Because change and complexity are inevitable, it promotes iterative design–code–test cycles, trade-offs, and backtracking when needed, while leveraging patterns to solve recurring architecture problems such as publisher–subscriber via the Observer model.

Through concise examples, the chapter surfaces common pitfalls—leaking changes due to tight coupling, overgrown classes with too many responsibilities, unwieldy inheritance hierarchies, hardcoded decisions that reduce flexibility, and APIs that surprise users—and shows how principles and patterns prevent them. The antidotes draw on core OO concepts: encapsulation to isolate what varies, abstraction to tame complexity, inheritance where appropriate, and polymorphism for runtime flexibility. Overall, it frames the journey to well-designed software as practical, example-driven, and grounded in OO design fundamentals tailored to Python.

A hierarchy of classes and subclasses. Does it have to be so complex? Good design techniques can simplify this data.
Publisher–subscriber is a common software architecture situation. One application component produces data that other application components consume. The Observer Design Pattern provides a model to solve this problem.
The Big Bang theory of application development. If we write lots of code in a prolonged marathon instead of developing the software iteratively, we can only hope that the Big Bang at the end will magically produce a working application. Unfortunately, that magic rarely happens.

Summary

  • Design is a disciplined engineering approach to creating a solution to a problem. In software engineering, the problem is to create working software, and the solution is a well-designed, sustainable application.
  • Well-designed software is better in many ways, such as being more reliable, flexible, and maintainable. Good design helps ensure that applications are completed on time and do what their clients expect.
  • It is possible to become a better programmer by using good software design techniques that include good design principles and design patterns.
  • Good design principles help make our code more flexible and able to handle changes such as new requirements. Design patterns are industry-proven models for creating solutions to common software architecture problems.
  • Software design starts by acquiring and analyzing an application’s requirements to ensure that we’re developing the right application. The application must do what it’s supposed to do.
  • Developing a well-designed sustainable application nearly always requires multiple iterations with backtracking over bad design decisions. It’s hard work. Don’t rely on a magical Big Bang at the end of a marathon coding session.
  • Good software design must deal with the major challenges of change and complexity.
  • The design principles and design patterns in this book are based on the object-oriented programming concepts of abstraction, encapsulation, inheritance, and polymorphism.
  • Encapsulation also means isolating the parts of a program that can change. Then, when changes do occur, they won’t leak out and cause changes to other parts of the program.

FAQ

What does this chapter mean by “software design”?It’s a disciplined engineering process for turning requirements into a reliable, maintainable application. The chapter frames design as applying proven principles (to improve code) and patterns (to solve recurring architecture problems) so you can move from requirements to a well-structured, sustainable solution.
How do design principles differ from design patterns?Principles are guidelines that improve code quality at the function, class, and collaboration level (for example, keeping responsibilities focused or hiding what varies). Patterns operate at a higher level: they are reusable design models that help you craft custom solutions to common architecture problems (for example, Observer for publisher–subscriber).
What are the key benefits of good software design?
  • Meets requirements and behaves as users expect
  • More reliable and easier to test, with fewer surprises
  • Efficient, avoiding hidden performance pitfalls
  • Flexible and scalable, accommodating new features without chaos
  • Supports collaboration and faster recovery from mistakes
  • Maintainable and easier for future developers to understand
  • Reduces rework and total cost over the application’s lifespan
  • Leverages sound techniques and patterns—resulting in code you can be proud of
How do I ensure I build the right application—and then build it right?First, gather, validate, and analyze requirements to confirm what the application must do. From those, identify initial classes and responsibilities. Then iteratively apply good design techniques and patterns to build the application correctly, aiming for an MVP that passes tests and can evolve safely.
Why does the chapter emphasize iterative development over a “Big Bang” approach?Successful design emerges through cycles of design–code–test, with tradeoffs and occasional backtracking. A long, one-shot coding marathon rarely yields a working, well-designed application; iterative learning and course correction do.
Why are change and complexity called the enemies of good design?Requirements, understanding, and environments change during and after development. If code isn’t prepared for change, fixes and features cascade through the codebase. Overcompensating can add complexity. Good design balances flexibility with simplicity—isolating variation while avoiding overengineering.
What common design problems does the chapter highlight?
  • Leaking changes: modifications in one class force edits in others due to tight coupling
  • Too much responsibility: bloated classes that do everything, making bugs hard to find
  • Inflexibility: hardcoded decisions (for example, always using Cat) that resist runtime choice
  • Surprises: code that produces unexpected results (for example, date formatting errors)
  • Recurring architecture needs: publisher–subscriber, solvable with patterns like Observer
How can I prevent changes in one class from “leaking” into others?Reduce coupling and hide volatility behind stable interfaces. Apply “encapsulate what varies”: introduce abstractions, delegate through interfaces, and keep clients dependent on behavior rather than concrete steps or internals, so internal changes don’t ripple outward.
Why is hardcoding object types inflexible, and what’s the alternative?Hardcoding (for example, always instantiating Cat) freezes decisions in source code, forcing edits when requirements change. Prefer making the choice at runtime via configuration, factories, or dependency injection, and rely on polymorphism so clients work with a Pet interface, not a specific subclass.
Who is this book for, and what Python context is assumed?It targets beginner to intermediate developers (and as a refresher for experienced ones) who know Python basics, data structures/algorithms, and OOP, and can write, run, and debug simple programs. Examples use core Python features and were tested on 3.12 (compatible from 3.6). While Python-focused, the principles and patterns apply to any modern OO language.

pro $24.99 per month

  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose one free eBook per month to keep
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime

lite $19.99 per month

  • access to all Manning books, including MEAPs!

team

5, 10 or 20 seats+ for your team - learn more


choose your plan

team

monthly
annual
$49.99
$399.99
only $33.33 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Software Design for Python Programmers ebook for free
choose your plan

team

monthly
annual
$49.99
$399.99
only $33.33 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Software Design for Python Programmers ebook for free