Single Responsibility Principle in C#: Writing Classes That Do One Thing Well
Letâs be honestâmost of us have, at some point, crammed way too much into a single class.
We start out with a nice little InvoiceManager
, and before long itâs calculating taxes, saving to disk, sending emails, and making coffee. It works⊠until it doesnât.
Thatâs where the Single Responsibility Principle (SRP) comes inâand itâs more than a fancy acronym. Itâs the âSâ in SOLID, and itâs all about one thing:
A class should have only one reason to change.
What That Actually Means
If a class has multiple responsibilities, it has multiple reasons to change. That might not sound dangerous, but it leads to brittle code, mysterious bugs, and update anxiety.
The moment you change the invoice saving logic, you risk breaking the calculation. Update the formatting? Hope it doesnât affect that PDF export. Sound familiar?
SRP says: donât mix concerns. Let each class focus on doing one thing really well.
A Common Example in C#
Letâs say weâre working with invoices. Hereâs something we might find in a typical project:
public class InvoiceProcessor
{
public void CalculateTotal(Invoice invoice)
{
// Logic to calculate total
}
public void SaveToFile(Invoice invoice)
{
// Logic to save invoice
}
public void PrintInvoice(Invoice invoice)
{
// Logic to print invoice
}
}
This looks neat at first glance, but the cracks show fast.
This one class is doing:
- Business logic (calculating totals)
- I/O (saving to file)
- Presentation (printing)
Thatâs three separate responsibilities, and that means three reasons to change. Not great.
âïž Letâs Refactor It
Following SRP, we break this up into smaller, focused classes:
public class InvoiceCalculator
{
public void CalculateTotal(Invoice invoice)
{
// Calculation logic
}
}
public class InvoiceSaver
{
public void SaveToFile(Invoice invoice)
{
// File-saving logic
}
}
public class InvoicePrinter
{
public void Print(Invoice invoice)
{
// Printing logic
}
}
Now weâve got one job per class, and everything is easier:
- Testing is simpler.
- Changes are isolated.
- Reuse becomes possible.
âBut Now I Have Too Many ClassesâŠâ
Yesâand thatâs a good thing.
Think of it like this: Would you prefer one kitchen drawer jammed with tools, or a set of organized drawers where everything has its place?
More classes can feel like overhead at first, but they pay off in readability, clarity, and peace of mind.
Youâll know where things are. And so will your teammates.
đ§Ș The Quick SRP Test
Hereâs a simple check list:
Can I explain what this class does in one sentence without using âandâ?
If your answer sounds like
It calculates totals and saves files and prints things⊠then yeahâSRP is being violated.
Why SRP Actually Matters
This principle isnât just for the clean-code purists. It helps in real-world scenarios:
- đ Debugging is easierâbecause you know where things live.
- đ§Ș Testing is cleanerâyou test one responsibility at a time.
- đ Changing requirements donât ripple through unrelated logic.
And when youâre knee-deep in a deadline, knowing your code wonât fall apart because you changed a formatting method? Thatâs a win.
Where SRP Sits in SOLID
Itâs the first of the SOLID principlesâand for good reason.
If your classes are tangled up with too many roles, the other principles become harder to apply. Get SRP right, and the rest of SOLID feels more natural.
Final Thoughts
The Single Responsibility Principle is like good storytelling: every class should have a clear plot.
If a class starts doing too much, it becomes confusing to read, hard to change, and painful to debug. But when each piece of code has a single, clear purpose, the whole system becomes easier to understandâand more fun to work on.
So next time youâre about to throw âjust one more methodâ into an already busy class, take a breath and ask:
Is this really the same responsibility⊠or is it time for a spin-off class?
You already know the answer.
Clean code always starts with clarity. SRP is step one.