Single responsibility principle - klasa, funkcja czy moduł powinny mieć tylko jeden powód zmiany. Stosując tę zasadę w praktyce tworzymy kod, który jest:
- prosty do zrozumienia
- łatwy do debugowania
- łatwy do zmiany - zmieniając pojedyncze zachowanie nie wpływamy na inne
- łatwy do testowania - np. za pomocą unit testów
- kod jest re-używalny - proste funkcje / klasy / moduły łatwo wdrożyć w nowych projektach
- można podciągnąć pod to zasadę: lepiej robić jedną rzecz a dobrze niż 10 źle :)
Jak rozpoznać ów powód do zmiany? Jednym aspektem będzie tu pewna praktyka, drugim pomocnikiem będzie zadawanie sobie pytania "Co ta klasa / funkcja / moduł właściwie robi?". Jeżeli znajdziemy kilka odpowiedzi na to pytanie - łamiemy zasadę pojedynczej odpowiedzialności.
Zobaczmy na poniższy przykład:
Odpowiedzialnością metody CreateReport jest:
Zobaczmy na poniższy przykład:
public class Report { private readonly string _connectionString; public Report(string connectionString) { _connectionString = connectionString; } public void CreateReport(int startId, string reportPath) { using var sqlConnection = new SqlConnection(_connectionString); sqlConnection.Open(); var sqlCommand = sqlConnection.CreateCommand(); sqlCommand.CommandText = "SELECT firstName, lastName, city, postalCode FROM person WHERE id > 200;"; using var dataReader = sqlCommand.ExecuteReader(); var personList = new List<Person>(); while (dataReader.NextResult()) { var person = new Person { LastName = (string) dataReader["lastName"], FirstName = (string) dataReader["firstName"], City = (string) dataReader["city"], PostalCode = (string) dataReader["postalCode"] }; personList.Add(person); } var report = new StringBuilder(); var xmlSerializer = new XmlSerializer(typeof(List<Person>)); using var stringWriter = new StringWriter(); xmlSerializer.Serialize(stringWriter, report); File.WriteAllText(reportPath, stringWriter.ToString()); } } public class Person { public string FirstName { get; set; } public string LastName { get; set; } public string City { get; set; } public string PostalCode { get; set; } }
Odpowiedzialnością metody CreateReport jest:
- pobranie danych z bazy
- stworzenie z danych XMLa (serializacja do XML)
- zapis danych do pliku
Jak widać mamy tutaj jak na tacy podane 3 powody do zmiany tej metody:
- źródło danych może zostać zmienione - zamiast bazy może to być plik, inny serwis itp
- format danych które zapisujemy - obecnie jest to XML, w przyszłości być może JSON lub CSV
- Raport zapisywany jest do pliku na dysku twardym, być może przyjdzie potrzeba zapisu danych do S3 na AWS
Powyższą metodę, a właściwie klasę wypadałoby podzielić na 3 mniejsze, dzięki czemu kod będzie prostszy w każdej z nich, testowalny, a w przypadku jego zmiany będzie to znacznie prostsze.
Brak komentarzy:
Prześlij komentarz