Skip to content

Software Design Patterns

Glossary

108 terms from Software Design Patterns, in plain words, each with the chapter that teaches it.

#

@abstractmethod
A decorator from the `abc` module that marks a method with no real body. Every child class must write its own version, as with `format_row` in the report classes.
@dataclass
A decorator that writes `__init__` (and more) for a class from its listed fields. `@dataclass(frozen=True)` makes the fields unchangeable after creation.

A

Abstract class
A class that inherits from `ABC` and exists only to be inherited from. You can't create one until a child fills in its abstract methods, so `Report()` raises a `TypeError`.
Abstract factory
An object with several make methods that builds a family of parts that belong together, such as a carrier and a label printer for one shipping company.
Adapter
A small wrapper class that holds a library object you can't edit and offers the interface your code expects. `UpsCarrier` turns UPS's answer in cents into dollars.
Anti-pattern
A common answer to a design problem that looks reasonable but causes more trouble than it solves. Examples are god objects and magic numbers.
assert
A Python statement that fails the test if its condition is False. pytest tests use it to check results, such as `assert order["total"] == total`.

B

Behavioral pattern
A pattern about how objects share work and make decisions together. Strategy and Observer are examples.
Builder
A pattern that collects the parts of a complicated object one call at a time, then checks them and makes the finished object in `build()`. `OrderBuilder` is the example.

C

Cache
Saved answers kept so the real work isn't repeated. A caching proxy asks the real carrier only once per number of lines.
Callable
A type hint for something you can call like a function. `Callable[[float], float]` means a function that takes one float and returns a float.
Chain of responsibility
A pattern where a request passes along a line of handlers. Each one deals with it (here, rejects the order) or passes it on, like the order checks `has_items`, `known_carrier` and `under_limit`.
Characterization test
A test that records what existing code does today, right or wrong, so a redesign can't change it by accident. For example, the three order totals from the old `place_order` (467.5, 42.6 and 31.25) become the expected values that the redesigned code must still produce.
Class attribute
A variable written in the body of a class, such as `name = "ups"`. Every instance shares it.
Class explosion
What happens when every mix of choices needs its own class, so the number of classes multiplies. Two yes/no choices make 4 classes and three make 8.
Closure
A function defined inside another that remembers the outer function's values after it returns. `percent_off(10)` returns a `discount` function that remembers `pct`.
Cohesion
How well the things inside one piece of code belong together. A function that only works out shipping has high cohesion, which is good.
Command
A pattern that turns an action into an object that knows how to do it (`run`) and reverse it (`undo`). The cart's Undo button is built from it.
Composite
A pattern that gives a single item and a group the same method, so a group's method asks each part and adds up the answers. The nested `Bundle` and `Item` classes both have `price()`.
Composition
Building an object from smaller part objects it holds and hands work to, instead of inheriting. A `Product` has a pricing part and a wrapping part.
Composition root
The one place, usually `main.py`, that builds the real parts and hands them to the code that needs them.
Constructor injection
Passing an object its dependencies through `__init__` so it keeps them for its whole life. `OrderLog(repo, clock, notifier)` does this.
Context manager
An object used with `with` that sets something up and always cleans up afterward, like `with open(...)`, which opens and closes a file.
Copy-paste programming
Repeating the same code in many places, so a fix must be made in each one and one is always missed.
Copying templates (copy.deepcopy, dataclasses.replace)
`copy.deepcopy` makes a full independent copy of a dict or list. `replace(weekly, qty=20)` returns a new frozen dataclass with some fields changed and leaves the original alone.
Coupling
How much one piece of code depends on the details of another. If shipping code reaches inside discount code, changing one may break the other, so you want loose coupling.
Creational pattern
A pattern about how objects get made. It moves the "which class, with which settings?" decision into one place.

D

Decorator
As a pattern, a wrapper with the same interface as the object it wraps. It does a little extra work, like logging each quote, and passes the call on. Python's `@` decorators do the same for functions.
defaultdict
A dict that creates a default value, such as an empty list, the first time you use a new key. `EventBus` uses it so a new event name starts with no listeners.
Delegation
Handing a job to an object you hold instead of doing it yourself. `Product.total` asks its pricing part and its wrapping part, then adds the answers.
Dependency
Anything a piece of code needs to do its job, such as a database, a notifier or the clock.
Dependency injection
Giving code its dependencies instead of letting it create or find them. That way a test can pass in fakes and avoid disk, real email and the real clock.
Depends
A FastAPI feature that calls a named function for each request and passes the result into your route function. It is dependency injection, much like a pytest fixture.
Design pattern
A named, reusable solution to a common design problem. It is a shape for your code, not a library or code to copy.
DI container
A library that builds objects and their dependencies from a list of rules. Python programs rarely need one, because plain calls in a composition root stay readable.
DIP
The SOLID principle that high-level code, like order rules, and low-level details, like printing, should both depend on an interface. You pass the detail in.
Duck typing
Python cares what an object can do, not what class it is: if it has the right methods, it works. `apply_discount` accepts any rule that has `applies` and `apply` methods.

E

Easy to change
The goal of design: a change like adding FedEx touches one small, obvious place and breaks nothing else.
Event
A named announcement that something happened, such as "order_placed". The code that emits it hands each listener the data and doesn't know what they do.
EventBus
A small subject class with `on` to add listeners and `emit` to call them. The order code announces "order_placed" without knowing who listens.

F

Facade
One simple function or class in front of several parts, so callers make one call and only the facade knows the steps. `checkout` and `OrderService` are examples.
Factory
A function or class whose job is making objects, so callers never need an `if` chain. `create_carrier("ups")` returns a ready carrier.
Factory method
A pattern where a parent class has a method that makes a part and each child overrides it to choose what to make. In `Shipment`, `SaverShipment` makes a USPS carrier.
Fake
A simple working stand-in for a real part in tests, such as `MemoryRepo` or a notifier that keeps messages in a list.
FastAPI and Django
Python web frameworks. FastAPI shows a route registry (`@app.get`), dependency injection with `Depends`, and middleware; Django and Flask use the same ideas under different spellings.
Fixture
A function marked `@pytest.fixture` that builds test data or parts. pytest calls it afresh for each test and passes the result to any test whose parameter has the same name.
Fragile base class
A parent class that its children depend on so closely that changing it quietly breaks them. Adding sales tax to `Product.total` would also tax wholesale products.
Framework
Code that runs your program and calls your code at the right moments, as pytest and FastAPI do.
Frozen dataclass
A dataclass made with `@dataclass(frozen=True)`, whose fields can't change after creation. Assigning to one raises `FrozenInstanceError`, so you use `replace` to get a changed copy.

G

Gang of Four
The nickname of the four authors of the 1994 book *Design Patterns*, which named 23 classic software design patterns.
Generator
A function that uses `yield` to hand back one item, then pauses until the loop asks for the next. It is the easy way to write your own iterator.
Global mutable state
Data at module level that any code can change, like the old `orders` list. Tests that share it can pass or fail depending on their order.
God object
One class or module that does far too much, such as a `Shop` class with 40 methods. The fix is to split it by reason to change.
Golden hammer
Using one favorite tool, such as a factory or class hierarchy, for every problem.

H

Handler
One link in a chain of responsibility. It deals with a request or passes it on.
Has-a / is-a
Two kinds of relationship. Inheritance says a wholesale product is a product. Composition says a product has a pricing rule.
Hook
The step a template method leaves for the caller or a child class to supply. In Python it is often a function passed in, such as `format_row`.

I

Inheritance
A child class reuses its parent's code. It works well for shallow "is a" cases such as exceptions, but deep trees become hard to change.
Injected clock
A function with no arguments that returns the current time, passed into code so a test can pass a fixed one. You pass `datetime.now` without brackets.
Interface
The set of methods that code expects an object to have, whatever its class.
Inversion of control
A framework calling your code instead of your code calling it: "don't call us, we'll call you". pytest finds and runs your tests, and FastAPI calls your routes.
ISP
The SOLID principle that code shouldn't depend on methods it doesn't use. Keep interfaces small, like a `Quoter` with just `quote`.
Iterator
An object that steps through a collection one item at a time without showing how it's stored. Every `for` loop uses one.

K

KISS
A rule of thumb: of two designs that both work, choose the one that's easier to read.

L

lambda
A way to write a small unnamed function in one expression, such as `lambda order: order["total"]`. It is handy as a sort key, a test clock or an entry in a table of factories.
Library
A set of tools your code calls when it wants to, such as `sorted` or `json.dump`.
Listener
A function called when an event it listens for is emitted, such as `send_email` for "order_placed".
LSP
The SOLID principle that a child class must work anywhere its parent works. `LockedCard` breaks it by refusing `top_up`.

M

Magic number
A number in code with no name saying what it means, like `75` and `0.85` in the old `place_order`. The fix is a named constant such as `FREE_SHIPPING_AT`.
Method chaining
Calling methods one after another because each ends with `return self`. `OrderBuilder` is used this way.
Middleware
Handlers that every web request passes through, such as logging or login checks, each able to stop the request. It is a chain of responsibility.
Mock
A test stand-in that also records how it was called so the test can check it. Python's `unittest.mock` module makes them.
mypy
A separate tool that reads type hints and warns when an object lacks a method. Python itself doesn't check them.

N

NotImplementedError
A built-in error meaning a child class must provide this method. A factory method's parent version raises it.

O

Observer
A pattern where the code that something happens in (the subject) keeps a list of listeners and calls each one, without knowing what they do. `logging` handlers work this way.
OCP
The SOLID principle that code should be open for extension but closed for modification. You add a new rule class instead of editing `apply_discount`.
Over-engineering
Building more structure than the problem needs, such as an abstract class, factory and registry for one discount.

P

parametrize
A pytest decorator that runs one test several times, once per row of inputs and expected results.
Plugin
Code a framework finds and runs to add a feature with no change to the framework. pytest has hundreds, and plugins are the open/closed principle at tool scale.
Premature abstraction
Adding an interface, base class or factory before you have two or three real cases. It guesses what will vary, and a wrong guess is harder to undo than plain code.
Protocol
A class from the `typing` module that lists the methods an interface needs, with `...` as each body. Classes match it just by having those methods.
Prototype
A pattern that makes new objects by copying a ready-made one and changing a little, like Bloom Café's weekly order.
Proxy
A wrapper with the same interface that controls access to the real object. It might create it lazily, check permissions or cache answers.
Publish/subscribe
Another name for the observer idea: the subject publishes events and listeners subscribe to them, with a message system between senders and receivers.
pytest
A Python testing framework. It finds functions named `test_...`, builds fixtures and passes them to tests by parameter name, and offers `pytest.raises` to check that code raises an error.

R

Registry
A table from names to classes or functions that is looked up when needed, like `CARRIERS` or a web framework's route table.
Repository
An object that stores and finds things for the rest of the code, so nothing else knows how they're stored. `MemoryRepo` replaces the global `orders` list, and a `SqliteRepo` (SQLite is a small file-based database) could replace it without other changes.
Rule of three
Write code the first time, notice the repeat the second, and extract the shared part the third time. By then you know what really varies.

S

Service locator
A global registry that code reaches into for its dependencies, like `REGISTRY["repo"]`. It hides dependencies again, and tests must change the global.
Simple factory
One function that knows every class and picks one, usually via a dict from names to classes. A new carrier needs one class and one dict entry.
Singleton
A class that allows only one instance and gives everyone that same instance. In Python a module is already one, since it loads only once.
SOLID
Five design principles named by their first letters: single responsibility, open/closed, Liskov substitution, interface segregation and dependency inversion. They are guides, not laws.
Spaghetti code
Code so tangled with ifs, globals and jumps that you can't follow one path through it.
SRP
The SOLID principle that a piece of code should have one reason to change. `price_items` changes only if line pricing changes.
State
A pattern that limits what an object can do based on its status. It can be a dict of allowed moves, or each state can be a class with the same methods.
State machine
A thing that is always in exactly one of a fixed set of states, with rules for which moves between them are allowed. An order goes from `placed` to `paid` to `shipped`.
Strategy
One interchangeable way of doing a job, where all versions have the same shape so the code using one doesn't care which it gets. In Python it is usually a function, like `percent_off(10)`.
Structural pattern
A pattern about how objects fit together: connecting pieces not made for each other, or wrapping one object in another.
Stub
A test stand-in that just returns fixed answers, such as a clock that always says 4:00 p.m.
Subject
In the observer pattern, the object where events happen and whose listeners subscribe, such as the event bus.
super()
A built-in that lets a child class call its parent's version of a method, as `super().total(qty)` does in `WholesaleProduct`.

T

Template method
A pattern that fixes a job's steps in one place and leaves one step, the hook, for the caller or a child class to supply. `make_report` takes a `format_row` function.
Transition
A move from one state to another, such as `paid` to `shipped`. A dict lists the allowed ones for each state.
Tree
A structure where items contain smaller items, like gift bundles inside bundles, down to single items.
Type hint
A note in the code, such as `-> bool` or `list[dict]`, saying what types a function expects and returns. Python doesn't enforce it, but tools like mypy read it.

U

Undo stack
A list of commands already run, newest on top. Undo pops the last one and reverses it.

W

Wrapper
An object that holds another and stands in front of it. Adapters, decorators and proxies are all wrappers.

Y

YAGNI
A rule of thumb: don't build for a future need until it's a real need, since most guessed needs never arrive or arrive in a different shape.