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.