The Single Responsibility Principle basically states that a class should have one (and only one) reason to change. Another way of saying the class should only do ONE THING. The benefits of designing classes this way includes:
- Easier to change - if you're changing the logic of the class (which only does one thing), then you don't have to worry about whether you're going to break the other "things" it does.
- Easier to understand - you can focus on the "one thing" the class is doing.
- Easier to unit test - your unit tests only need to worry about the one thing the class does.
We were in the middle of a problem at work where we needed a certain set of classes (Decisions) to translate to another set of classes (Instances). The reason for this was the "originating" (Decisions) class wasn't XmlSerializable, and we needed to send it across the wire (the reason for THAT was due to looped relationships within the object graph, eg "child pointing back to parent"). The "translation mechanism" we were using (Instances) happened to be a set of classes (that WERE serializable) we were using to interface with an external billing system.
By using this "translation mechanism" for our purposes, we were essentially violating the SRP at the architectural level. The class was responsible for:
- Interfacing our Decisions class with the external Billing system.
- Transmitting our Decisions class across a web service
Thing got tricky because the translation wasn't exactly direct - there was information lost in the translation, and we had to infer several properties, relationships, etc on the Decisions class from OTHER properties that were intended for use by the Billing system. And if these "Billing" properties didn't behave exactly like we wanted, we were faced with the prospect of changing them, and potentially impacting the Billing system translation. To make things much worse, we had no unit testing in place for what the Billing system required.
We've reached the point where the changes required (while seemingly minor) were getting more frequent, and our comfort level (fear) around the Billing System was enough to make us take stock of the entire situation. We've decided to rollback any of these "accomodating" changes we've made, and attempt to get the original (Decisions) class to serialize, rather than using the Instances class to perform the translation. And if THAT doesn't work, then we'll probably create a separate mechanism for getting it sent across, rather than trying to use the Instances class.
The Instances class already has a responsibility, and burdening it with this second one just got too scary.