Skip to main content

One Reason to Change

The Single Responsibility Principle is the S in SOLID, five rules for designing code that stays easy to change. It says: a type should have one job — and therefore only one reason to change.

When one type saves orders and sends emails, it changes when the storage changes and when the email text changes. Two jobs, two reasons, twice the risk of breaking one thing while touching the other.

In Python the rule applies to classes, their methods, and modules: keep each one focused on a single task.


Too Many Jobs in One Class

This order processor works — but it stores the order, writes the confirmation text, and "sends" it, all in one method. Testing the email text alone is impossible, and reusing the storage part elsewhere means dragging the email code along.

One class that does everything

process() mixes two jobs: storing and notifying. Any change to either one means editing — and re-testing — this same class.

Prompt
Write a Python program with an OrderProcessor class whose process method does two jobs at once: it prints that the order was saved to storage and prints a confirmation email text for the customer. Process one order to show it works, as a starting point for the Single Responsibility discussion.
Output: complete Python program

One Job per Class

The fix: one class per job. OrderStore only stores, EmailSender only sends. A small function coordinates them.

The output is the same — but now each part can be changed, tested, and reused on its own.

Split into two classes

Same behavior, separated: the store knows nothing about emails, the sender knows nothing about storage. The process_order function just connects them.

Prompt
Refactor the order processing into two Python classes with one job each: an OrderStore with a save method that prints the storing step, and an EmailSender with a send_confirmation method that prints the email. Add a process_order function that calls both. Process one order and show the same output as before.
Output: complete Python program

The payoff: reuse without fear

Because the sender is its own class, it sends a shipping notice too — no storage code involved. And the store archives an order without composing a single email. Each class grew inside its one job.

Prompt
Using the separated OrderStore and EmailSender classes in Python, show the payoff of single responsibility: send a shipping notification with the same sender without touching storage, and archive an order with the store without sending any email. Print each action.
Output: complete Python program