Blog
Blog HelionBlog HelionBlog HelionBlog Helion
  • Artykuły
  • Autorzy
  • Recenzje
  • Konkursy

Mnemonik SOLID — S jak Single Responsibility Principle

    Blog.helion.pl Artykuły Mnemonik SOLID — S jak Single Responsibility Principle
    NastępnyPoprzedni

    Mnemonik SOLID — S jak Single Responsibility Principle

    By Helion | Artykuły, Programowanie | Brak komentarzy | 21 czerwca, 2016 | 2

    Bardzo lubię powiedzenie „lepiej nie wymyślać koła od nowa”, ponieważ pasuje do wielu obszarów naszego codziennego życia, w tym programowania. Pisząc kod, bardzo często rozwiązujemy problemy, nad którymi ktoś już wcześniej pracował.

    W takich sytuacjach lepiej jest re-użyć pewnych istniejących rozwiązań, niż tworzyć coś niesprawdzonego od nowa. W dzisiejszych czasach mamy tysiące bibliotek i frameworków — w większości przypadków wystarczy tylko dobrze poszukać.

    Sam w obszarze programowania nie ograniczałbym się jedynie do re-używania istniejącego kodu, starałbym się również re-używać tych najlepszych praktyk, wymyślonych przez specjalistów. W pewnym sensie do takich praktyk można zaliczyć słynny mnemonik Solid autorstwa Roberta C. Martina. Z pewnością wielu z Was o nim słyszało — mniej lub więcej — wydaje mi się jednak, że to temat godny pogłębienia, ponieważ jeśli dobrze poznamy pięć zawartych tu reguł, to kod po prostu obroni się sam.

    Niniejszy tekst rozpoczyna serię pięciu postów, z których każdy będzie opisywał kolejną regułę Solid. Rozpoczynamy oczywiście od literki S, która reprezentuje wyrażenie Single Responsibility Principle.

     

    Single Responsibility Principle

    Zasada jednej odpowiedzialności (bo tak właśnie tłumaczymy ten angielski termin) mówi, że każda z klas powinna mieć tylko jedną odpowiedzialność. Można też powiedzieć inaczej — w razie zmiany uwarunkowań powinien istnieć tylko jeden powód do modyfikacji zawartości wskazanej klasy. SRP mówi również o implementacji komunikacji za pomocą publicznych interfejsów.

    Spójrzmy na pierwszy z brzegu przykład. Tworząc oprogramowanie, bardzo często spotykamy się z raportami. Te mogą być generowane na podstawie zgromadzonych w bazie danych, które później zostają zrzucone do pliku wyjściowego typu PDF. Ignorując SRP, moglibyśmy stworzyć klasę RaportGenerator, która wewnętrznie:

    – pobiera informacje z bazy danych;

    – tworzy plik PDF.

    Mamy tu, jak widać, dwie różne odpowiedzialności — nie mówiąc o samym fakcie sklejania tego wszystkiego w całość. I choć kompletny kod mógłby się zmieścić prawdopodobnie w kilkuset liniach, co na pozór „nie wygląda źle”, już w tym momencie łamie on podstawowe zasady SRP. W kolejnych akapitach przedstawię prostą dekompozycję, która pozwoli na rozwiązanie tego problemu i dopasowanie się do reguły SRP.

     

    Przykład praktyczny

    Naszym studium przypadku będą klasa RaportGenerator oraz dwie klasy od niej zależne. Na potrzeby przykładu nie będziemy skupiać się na logice związanej z dostępem do bazy danych czy generowaniem PDF-ów, ale na samych interfejsach i abstrakcji. Chodzi mi przede wszystkim o przygotowanie działającego przykładu.

    Zaczniemy od zdefiniowania interfejsów dla dwóch klas zależnych:

    
    
    public interface IDatabaseManager
    {
    	IEnumerable<string> GetReportData(DateTime date);
    }
    
    public interface IFileWriter
    {
    	void Open();
    	void WriteData(IEnumerable<string> data);
    	void Close();
    }
    

    W kolejnym kroku musimy wygenerować przykładowe implementacje tych dwóch klas:

     

    public class MyDatabaseManager : IDatabaseManager
    {
    	public IEnumerable<string> GetReportData(DateTime date)
    	{
    		string str = date.ToString();
    		for(int i = 0; i < 10; ++i)
    		{
    			yield return str + "_" + i;
    		}
    	}
    }
    
    public class PdfFileWriter : IFileWriter
    {
    	public PdfFileWriter(string filePath)
    	{
    		Console.WriteLine($"Pdf file with path: {filePath}");
    	}
    
    	public void Open()
    	{
    		Console.WriteLine("PDF file open");
    	}
    
    	public void WriteData(IEnumerable<string> data)
    	{
    		Console.WriteLine($"Write {data.Count()} records to PDF file");
    	}
    
    	public void Close()
    	{
    		Console.WriteLine("PDF file close");
    	}
    }
    
    

    Poszedłem w tym przypadku po linii najmniejszego oporu, ponieważ, tak jak wcześniej pisałem, nie chodzi tutaj o obsługę bazy danych ani PDF-y 😉 Powyższe klasy zadaniowe implementują stworzone wcześniej interfejsy i realizują wydzielone dla nich zadania. Spoiwem dla powyższego kodu jest klasa ReportGenerator, która wykorzystuje wszystko, co napisaliśmy wyżej:

    public class ReportGenerator
    {
    	public void GenerateReport(string filePath, DateTime date)
    	{
    		IDatabaseManager databaseManager = new MyDatabaseManager();
    		var reportData = databaseManager.GetReportData(date);
    
    		IFileWriter pdfWriter = new PdfFileWriter(filePath);
    		pdfWriter.Open();
    		pdfWriter.WriteData(reportData);
    		pdfWriter.Close();
    	}
    }
    
    

    W moim przykładzie obiekty są generowane na żądanie w kodzie metody, ale oczywiście nic nie stoi na przeszkodzie, by w produkcyjnym rozwiązaniu użyć IoC, którego jednak nie chciałem tutaj wtłaczać, by nie zaciemniać przykładu. Efekt naszej pracy można sprawdzić w aplikacji konsolowej:

    public class Program
    {
    	public static void Main(string[] args)
    	{
    		ReportGenerator reportGenerator = new ReportGenerator();
    		reportGenerator.GenerateReport("myreport.pdf", new DateTime(2016, 05, 9));
    	}
    }
    

    Jak widać, nawet na prostych klasach łatwo jest pokazać ideę SRP. Kod, który podzieliliśmy właściwie na trzy klasy, często nie wyglądałby tragicznie, będąc w jednej. Można by powiedzieć: ot „prosta” klasa na kilkaset linii.

    Co dostaliśmy w zamian? Łatwość rozwoju, jawny podział na odpowiedzialności oraz publiczne interfejsy. Wiemy również, kto rozmawia z bazą danych, kto operuje na plikach, a kto jest w stanie złączyć to wszystko w jedną, logiczną całość. Same korzyści 🙂 I o to chodziło!

     

    Jerzy Piechowiak

    Altcontroldelete.pl

     
     

     Szukasz książki do C#? Kliknij TU lub zerknij poniżej:

     

     

    .net, altcontroldelete, c#, design patterns, Jerzy Piechowiak, kod, kodowanie, programista, programowanie, Single Responsibility Principle, SOLID
    Avatar

    Helion

    Więcej postów od Helion

    Podobne posty

    • Mnemonik SOLID — O jak Open/Closed Principle

      By Helion | Brak komentarzy

        Tworząc oprogramowanie, bardzo często stoimy przed dylematem: czy pisać kod szybko, czy porządnie. Oczywiście, o ile tylko mamy możliwość, wybierajmy tę drugą opcję, jednak taka decyzja generuje nowy problem, ponieważ na wczesnym etapie procesuCzytaj więcej…

    • Autofac — różne sposoby rejestracji usług

      By Jerzy Piechowiak | 2 komentarze

      Gdy dobrych kilka lat temu zaczynałem programować w C#, nie miałem pojęcia o czymś takim jak kontener IoC. Każdy obiekt tworzyłem klasycznie — poprzez zastosowanie słowa kluczowego new: StringBuilder sb = new StringBuilder();

    • Refaktoryzacja – kiedy jest niezbędna?

      By Helion | Brak komentarzy

      Po co refaktoryzować?   Nie twierdzę, że refaktoryzacja jest lekarstwem na wszelkie programistyczne bolączki. Jednak z pewnością jest wartościowym narzędziem, parą kleszczy, które pozwalają trzymać kod w potrzasku i panować nad nim w pełni. Refaktoryzacja możeCzytaj więcej…

    • Wzorzec projektowy adapter

      By Jerzy Piechowiak | Brak komentarzy

      Bardzo trudno jest napisać fragment kodu, o którym moglibyśmy powiedzieć, że jest idealny. Praktycznie niemożliwe jest zrobienie takiej rzeczy za pierwszym razem.

    • Wzorzec projektowy strategii

      By Jerzy Piechowiak | Brak komentarzy

      Programowanie, wbrew obiegowym opiniom, nie jest aż takie trudne. Wypuszczenie nawet prostych aplikacji mobilnych czy stron nie wymaga dzisiaj dużych nakładów sił. Największym problemem jest napisanie takiego kodu, który będzie łatwo rozszerzalny i będzie miałCzytaj więcej…

    NastępnyPoprzedni

    Znajdź post

    Bądźmy w kontakcie

    Książka dnia

    Algorytmy, struktury danych i techniki programowania dla programistów Java

    Autor: Piotr Wróblewski

    Cena: 33.50 zł 67.00 zł
    (Cena e-booka: zł zł)

    O 33,5zł taniej!

    kup teraz

    Ostatnie wpisy

    • Błyskawiczny kurs pisania skryptów powłoki
    • Przykładowa aplikacja webowa zaimplementowana w ASP .NET Core
    • Wprowadzenie do .NET Core: instalacja, konfiguracja, pierwsza aplikacja w systemie Linux
    • Grupa Helion zaprasza na szkolenia stacjonarne!
    • Hello World! Czym jest programowanie?

    Tagi

    .net agile altcontroldelete asp.net c# czysty kod debugowanie design patterns e-biznes emarketing Google Google Analytics hacking Jerzy Piechowiak kod kodowanie Krzysztof Marzec książka Maciej Dutko magazyn programista Magdalena Daniłoś marketing MVVM onepress organizacja czasu praca prograista programista programowanie prokrastynacja rafał kocisz reklama rozwój software craftsman SOLID startup techniki programowania testowanie video marketing visual studio WPF wzorce projektowe youtube zarządzanie czasem zarządzanie projektami

    Archiwum

    • lipiec 2017
    • czerwiec 2017
    • maj 2017
    • kwiecień 2017
    • marzec 2017
    • luty 2017
    • styczeń 2017
    • grudzień 2016
    • listopad 2016
    • październik 2016
    • wrzesień 2016
    • lipiec 2016
    • czerwiec 2016
    Blog wydawnictwa
    Informatyka w najlepszym wydaniu
    Strona wydawcy:
    www.helion.pl
    Księgarnia Helion.pl
    Nowości
    Bestsellery
    Promocje
    Bądźmy w kontakcie:
    Chcesz zostać autorem?
    Masz pytania do redakcji?
    Napisz do nas »
    • Artykuły
    • Autorzy
    • Recenzje
    • Konkursy
    Blog Helion