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.