Zasada jednej odpowiedzialności

Zbierz razem rzeczy, które zmieniają się z tych samych powodów. Oddziel te, które zmieniają się z różnych powodów.

Robert C. Martin

Każda funkcja, klasa lub moduł powinna mieć jedną odpowiedzialność i ta odpowiedzialność powinna być w niej zamknięta.

Kod programu powinien być podzielony na klasy i każda z tych klas powinna istnieć w jednym celu. Każda klasa powinna zawierać metody wykonujące podobne zadania. Oznacza to, że podobne funkcje (wykonujące podobne zadania) należy zebrać w jednej klasie.

Rozważmy przykładową klasę której zadaniem jest wygenerowanie raportu:

public class ReportGenerator {
    // metoda wyświetla raport
    public void printReport (String reportId) {
        System.out.println(generateReport(reportId));
    }
    
    // metoda generuje raport na podstawie przekazanego Id
    private String generateReport (String reportId) {

        // logika odpowiedzialna za wygenerowanie raportu

        return wygenerowanyRaport;
    }
}
public class Runner {
    public static void main (String [] args) {
        ReportGenerator generator = new ReportGenerator();
        generator.printReport("123");
}

Powyższa klasa ma 2 odpowiedzialności, co oznacza, że mogą istnieć 2 powody do modyfikacji tej klasy:

  • metoda generateReport generuje raport na podstawie przekazanego ID,
  • a metoda printReport wyświetla wygenerowany raport.

Klasa powinna mieć tylko jeden powód do zmiany.

Robert C. Martin

Poprawiona implementacja

Rozbijmy tę klasę na 2 oddzielne klasy.

Klasa ReportGenerator odpowiada tylko za generowanie raportów:

public class ReportGenerator {   
    // metoda generuje raport na podstawie przekazanego Id
    public String generateReport (String reportId) {

        // logika odpowiedzialna za wygenerowanie raportu

        return generatedRaport;
    }
}

a ReportPrinter za wyświetlanie raportów:

public class ReportPrinter {   
    // metoda wyświetla raport
    public void printReport (String reportToPrint) {
        System.out.println(reportToPrint);
    }
}
public class Runner {
    public static void main (String [] args) {
        ReportGenerator generator = new ReportGenerator();
        ReportPrinter printer = new ReportPrinter();
        
        String generatedReport = generator.printReport("123");
        printer.printReport(generatedReport);        
}

Zalety kodu zgodnego z zasadą jednej odpowiedzialności

Kod napisany zgodnie z zasadą jednej odpowiedzialności jest łatwiejszy w utrzymaniu. Funkcje, klasy i moduły napisane zgodnie z tą zasadą są mniejsze, bardziej spójne. W przypadku wprowadzania modyfikacji łatwiej uniknąć błędów.

Elementów napisanych zgodnie z zasadą jednej odpowiedzialności łatwiej ponownie użyć. Są prostsze, mniej specyficzne, bardziej czytelne. Kod jest lepiej zorganizowany i bardziej modularny.