Zasada pojedynczej odpowiedzialności

Klasa lub moduł powinna mieć tylko jedną odpowiedzialność.
W praktyce oznacza to, że klasa powinna robić jedną rzecz, a wszystko inne, co nie jest bezpośrednio z nią związane, powinno być przekazane do innej klasy. Dzięki temu podejściu kod staje się bardziej modularny i mniej podatny na błędy.

Zasada pojedynczej odpowiedzialności ułatwia:

  • Ograniczanie ryzyka błędów – Zmieniając jeden aspekt działania klasy, nie ryzykujesz, że uszkodzisz inne.
  • Testowanie – Testy dla pojedynczej odpowiedzialności są prostsze, bo nie musisz sprawdzać wielu funkcji jednocześnie.
  • Rozszerzanie aplikacji – Dobrze podzielone klasy można łatwiej rozszerzać, dodając nowe funkcje bez ryzyka konfliktów z innymi częściami aplikacji.

Kod przed zastosowaniem zasady pojedynczej odpowiedzialności:

public class Order {
    private List<Item> items;

    public double calculateTotalPrice() {
        // Obliczanie całkowitej ceny zamówienia
        double total = 0;
        for (Item item : items) {
            total += item.getPrice();
        }
        return total;
    }

    public void saveToDatabase() {
        // Logika zapisu zamówienia do bazy danych
        System.out.println("Order saved to database.");
    }

    public void sendConfirmationEmail() {
        // Logika wysyłania e-maila potwierdzającego zamówienie
        System.out.println("Confirmation email sent.");
    }
}

W tym przypadku klasa Order ma trzy odpowiedzialności: obliczanie całkowitej ceny zamówienia, zapis do bazy danych i wysyłanie e-maila. Zgodnie z SRP, te obowiązki należy rozdzielić na różne klasy.

Kod po zastosowaniu zasady pojedynczej odpowiedzialności:

Klasa Order — odpowiedzialna tylko za zarządzanie zamówieniem i obliczanie całkowitej ceny:

public class Order {
    private List<Item> items;

    public Order(List<Item> items) {
        this.items = items;
    }

    public double calculateTotalPrice() {
        double total = 0;
        for (Item item : items) {
            total += item.getPrice();
        }
        return total;
    }

    public List<Item> getItems() {
        return items;
    }
}

Klasa OrderRepository — odpowiedzialna tylko za zapis zamówienia do bazy danych:

public class OrderRepository {
    public void save(Order order) {
        // Logika zapisu zamówienia do bazy danych
        System.out.println("Order saved to database.");
    }
}

Klasa EmailService — odpowiedzialna tylko za wysyłanie e-maila z potwierdzeniem:

public class EmailService {
    public void sendOrderConfirmation(Order order) {
        // Logika wysyłania e-maila potwierdzającego zamówienie
        System.out.println("Confirmation email sent.");
    }
}

Klasa pomocnicza Item:

public class Item {
    private String name;
    private double price;

    public Item(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public double getPrice() {
        return price;
    }

    public String getName() {
        return name;
    }
}

Użycie klas z Zasadą pojedynczej odpowiedzialności:

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        Item item1 = new Item("Laptop", 1500);
        Item item2 = new Item("Mouse", 50);

        Order order = new Order(Arrays.asList(item1, item2));
        OrderRepository orderRepository = new OrderRepository();
        EmailService emailService = new EmailService();

        double totalPrice = order.calculateTotalPrice();
        System.out.println("Total price: " + totalPrice);

        orderRepository.save(order);
        emailService.sendOrderConfirmation(order);
    }
}

Klasa Order zajmuje się teraz tylko zarządzaniem danymi zamówienia i obliczaniem ceny.
Klasa OrderRepository odpowiada za zapis zamówienia do bazy danych.
Klasa EmailService jest odpowiedzialny za wysyłanie e-maila potwierdzającego.

Takie podejście upraszcza kod, czyni go bardziej modularnym, łatwiejszym do testowania i rozszerzania. Każda klasa ma jedną odpowiedzialność, co sprawia, że zmiany w jednej klasie nie wpłyną na inne aspekty systemu.