EDIT 2017/02/13 - Check the repo as it is now. The first example is solving with SRP in mind, but later on introducing other principles of SOLID.. I should've explained that better.
I'm trying to get a good example down of a violation and how to solve the SR principle. I want to be sure however it is good, and that I'm not writing down anything that doesn't make sense - so any input is welcome, or how I could better explain this. I'm doing this to teach myself and understand the "S" of SOLID better by theory and example.
Here's the example: https://github.com/learnasyougo/S.O.L.I.D#single-responsibility-principle - or below as a reference.
Single Responsibility Principle
A class should only have only one reason to change.
Violation example
Class Person
is responsible for holding person related data, it also holds has a function Format
which outputs this person data to a given format. Currently this method accepts a parameter on which the function decides which algorithm to use return the data in the required format.
The example below violates the single responsibility principle because the class Person
now is responsible for keeping data of of the person and formatting that data.
class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
public Gender Gender { get; set; }
public DateTime DateOfBirth { get; set; }
public string Format(string formatType) {
switch(formatType) {
case "JSON":
// implement JSON formatting here
return jsonFormattedString;
break;
case "FirstAndLastName":
// implementation of first & lastname formatting here
return firstAndLastNameString;
break;
default:
// implementation of default formatting
return defaultFormattedString;
}
}
}
How to fix?
We can solve this by making sure that the class Person
is only responsible for keeping the data and not responsible for formatting that data. Thus we will extract out the method Format
and introduce another class that is responsible for formatting a book.
class PersonFormatter {
public string Format(Person person, string formatType) {
switch(formatType) {
case "JSON":
// implement JSON formatting here
return jsonFormattedString;
break;
case "FirstAndLastName":
// implementation of first & lastname formatting here
return firstAndLastNameString;
break;
default:
// implementation of default formatting
return defaultFormattedString;
}
}
}
class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
public Gender Gender { get; set; }
public DateTime DateOfBirth { get; set; }
}
We could argue that this example still holds violations against SOLID, and that is true. As the format
method itself still holds too much responsabilities as it has to implements too much details on how it is being formatted. We'll solve this later one with oneor more of the other principles: namely the Dependency Inversion principle and the Interface Segragation Principle. But at least now we can change the implementation of the formatting of a Person without affecting the Person class itself - as the SRP states.