Design and architecture in Python
You organise growing Python projects with patterns, layers and dependency management and build code bases that are easy to test and change.
Level 401 · 17 lessons · 18 practice labs
Lessons
Design principles
- SOLID principles in Python
- Coupling and cohesion
- Dependency injection without a framework
- Designing errors: exception or return value?
- Short task: untangle intertwined modules
Patterns
- Strategy and factory patterns
- The observer pattern and events
- Adapter and facade
- The command pattern and undo
- State machines
- Short task: a design that routes alerts to channels
Architecture
- Layered and hexagonal architecture
- Domain models and value objects
- Managing settings from one source
- Plugin architecture and entry points
- Short task: make the data source swappable
Capstone
- Capstone: turn a large script into a layered application
Practice labs
- Passing the clock in from outside: Give a shift calculator that is untestable because it calls datetime.now() internally a clock parameter and write tests with a fixed time.
- Splitting a report class that does everything: Split a single class that reads data, computes and sends e-mail into three responsibilities while the behaviour tests pass unchanged.
- Untangling a circular import: Separate order and invoice modules that import each other by extracting a shared interface so the import-cycle check and tests pass cleanly.
- Fixing a function that returns error codes: Change a stock function that returns -1 on failure, which callers forget to check, to raise a meaningful exception and update the callers.
- Building an exception tree for payment errors: Give a payment module that raises bare Exception a tree separating transient from permanent errors so retries run only for the transient ones.
- Translating errors at a layer boundary: In an app that leaks database exceptions straight to the interface, translate them to domain errors in the repository layer and show by test that no internals reach the user.
- Separating shipping fee rules into strategies: Split a shipping fee calculation written as a long if chain into selectable strategy functions and add a new rule without touching existing code.
- Announcing stock changes to subscribers: Change a class that calls e-mail and logging code directly when stock drops to publish events, with subscribers that can be added and removed and that keep working when one fails.
- A list editor with undoable commands: Turn add, delete and move operations into command objects and test unlimited undo and redo with random operation sequences.
- Writing an adapter for an old SMS client: Write an adapter that fits an old SMS client with different method names to the application's notification interface.
- A state machine for a support ticket: Define the allowed transitions between a ticket's open, pending, resolved and closed states with a table and raise an error on a forbidden one.
- Opening one door onto scattered backup steps: Write a facade for backup code whose callers know the compress, encrypt, upload and verify steps one by one, and clean up when a step fails midway.
- Reading settings from a single source: Gather os.environ reads scattered across modules into one frozen settings object and report a missing required setting at start-up.
- Defining a value object for money: Add an immutable Money value object to code that carries amounts as floats and currency as a separate string, and forbid adding different currencies.
- Making the data source swappable: Put business logic that writes straight to a file behind a port interface and show the in-memory and SQLite adapters pass the same contract tests.
- Putting a proxy in front of a slow client: Write a proxy class offering the same interface as a slow exchange-rate client that caches responses briefly, with no change to the calling code.
- A traffic light from a transition table: Define a traffic light's states and allowed transitions in a dictionary table and raise an error when a transition not in the table is requested.
- An order state machine with guarded transitions: Add guards that block shipping before payment, a transition history and an undo step on cancellation to an order state machine, with invalid transitions leaving the state unchanged.
About this course
You organise growing Python projects with patterns, layers and dependency management and build code bases that are easy to test and change.
What you will learn
- Design principles
- Patterns
- Architecture
- Capstone
Prerequisites
You should have practised the topics of the same path up to level 301.
Lab environment
Lessons run in your own Kali Linux terminal that opens in the browser. Nothing to install; the lab starts clean in every lesson.
Frequently asked questions
- Is this course right for my level?
- The course is at level 401; it assumes you know the topics of the lower-level courses.
- Is there anything to install?
- No. Every lesson runs in your own lab environment that opens in the browser.
- How do lessons work?
- Each lesson has 8 to 10 steps and a short quiz. Early steps show the command to type, later steps give less help; if two attempts fail, the solution opens.
- Can I try it for free?
- Yes. The first three lessons of every course are free.