SRP – Single Responsibility Principle

Cześć drogi czytelniku 🙂 ! Dzisiejszy artykuł przeznaczyłam na opisanie SRP czyli w przetłumaczeniu “zasada pojedynczej odpowiedzialności”. Dowiedzmy się więc tego z dalszej części :).

Trzeba tutaj zaznaczyć że wymieniona reguła wchodzi w składa zasad SOLID i to właśnie SRP reprezentuje pierwszą literę “S” z SOLID-u.

No dobrze ale o czym ta reguła mówi?

SRP mówi o pojedynczej odpowiedzialności która odnosi się do klasy. W kontekście programowania oznacza to że powinien istnieć tylko jeden powód modyfikacji klasy.

Ale co to dokładnie oznacza?

Z punktu widzenia klienta może wyglądać to tak że zawsze istnieje jeden powód do zmiany. Aby więc to lepiej wytłumaczyć posłużę się przykładem. Przykładowo więc mamy kasę Car która posiada atrybuty, konstruktor lub konstruktory, getery i setery, metody equals i hashcode, toString. Co prawda klasa na pierwszy rzut oka zawiera różne typy metod: pobierające (get), wpływające na obiekt (set) oraz sprawdzające czy dany obiekt w kolekcji jest na pewno unikatowy. Kontynuując te rozważania możemy zauważyć że klasa jest odpowiedzialna tylko i wyłącznie za zdefiniowanie obiektu i nie znajdziemy tutaj logiki biznesowej. Dzięki czemu wiemy że gdy nasze auto zostanie rozbudowane o dodatkowe gadżety np. w postaci sufitu z gwiazdami 🙂 od raz będziemy wiedzieć do której klasy dodać taki atrybut.

public class CarClass {   
   private string color;
   private LocalDate yearOfProduction;
   private String model;
   private Owner owner;
   private CarCeiling;
}

Reguła ta ma zostawanie nie tylko w klasach ale również w pojedynczych metodach. Wyobraźmy sobie sytuacje że metoda w klasie CarReader posiada metodę createCar() która zarówno zajmuje się tworzeniem obiektu jak i jego wypisaniem go na konali. W tym momencie metoda ta posiada już dwie odpowiedzialności.

Proszę spójrz na poniższy przykład który obrazuje omawianą sytuację.

public class CarReader {

    private Scanner cs = new Scanner(System.in);

    public Car createCar() {
        System.out.println("Podaj kolor auta: ");
        String color = cs.nextLine();
        System.out.println("Podaj datę produkcji: ");
        String date = cs.nextLine();
        System.out.println("Podaj model: ");
        String model = cs.nextLine();
        System.out.println("Car's attributes: " + color +" " + date +" " + model);
        return new Car(color, date, model);
    }
Wynik powyższej metody został pokazany poniżej. 
Źródło: Archiwum własne.

Aby więc zachować zasadę SRP należy rozbić nieco tą metodę np. w taki sposób:

public class CarReader {

    private Scanner cs = new Scanner(System.in);

    public Car createCar() {
        System.out.println("Podaj kolor auta: ");
        String color = cs.nextLine();
        System.out.println("Podaj datę produkcji: ");
        String date = cs.nextLine();
        System.out.println("Podaj model: ");
        String model = cs.nextLine();
        return new Car(color, date, model);
    }

    public void carInfo() {
        String carString = createCar().toString();
        System.out.println("Car: " + carString);
    }
}

Zobaczmy wynik po modyfikacji:

Źródło: Archiwum własne.

Klasa powinna odpowiadać tylko i wyłącznie za jedną (jakąś konkretną) logikę w naszym systemie. W kontekście SRP odpowiedzialność oznacza “powód zmiany”. Nieodłącznym elementem pisania projektu są stałe zmienne wymagania od klientów. Więc gdy zmieniają się wymagania co do projektu to będą one manifestowane poprzez zmianę odpowiedzialności pomiędzy klasami. “Każda odpowiedzialność jest osią zmian”. Jeśli klasa ma więcej niż jedną odpowiedzialności to zmiana jednej z nich może prowadzić do zaburzenia w funkcjonowaniu pozostałych odpowiedzialności klasy (jest to wtedy “kruchy” projekt). Może to tym samym doprowadzić do zepsucia projektu w sposób nieoczekiwany. 

Jeśli uważasz powyższy tekst za pomocny, podziel się z kimś komu może być przydatny, na pewno będzie Ci wdzięczny. A tymczasem do zboczenia w kolejnym wpisie 🙂 🙂 !!

Leave a Comment

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *