SOLID to pięć zasad dotyczących dobrych praktyk programistycznych w programowaniu obiektowym, których stosowanie przyczynia się do pisania łatwiejszego w zrozumieniu, prostszego w utrzymaniu i w rozwijaniu kodu. Termin został wprowadzony przez amerykańskiego programistę Roberta C. Martina (Uncle Bob). Jest to skrót, który został utworzony od pierwszych liter pięciu zasad. Pierwsza litera, a więc S, oznacza zasadę Single Responsibility Principle – zasadę jednej odpowiedzialności. Mówi ona o tym, że każda klasa nie powinna mieć więcej niż tylko jedną odpowiedzialność oraz nie powinien istnieć więcej niż jeden powód do modyfikacji klasy. Jeśli klasa ma więcej niż jedną odpowiedzialność, wtedy istnieje więcej niż jeden powód do jej zmiany.

Przyjrzyjmy się poniższemu przykładowi.

Product.java

package online.shop;

public class Product {
    private String name;
    private double price;
    private double taxRate;

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

    public double calculateTax() {
        return this.price * this.taxRate;
    }

    public double getPrice() {
        return price;
    }

    public double calculateTotalPrice() {
        return this.price + calculateTax();
    }

}

Załóżmy, że prowadzimy sklep internetowy. Posiadamy jedną klasę Product, która zawiera pola takie jak nazwa, cena, wielkość procentową podatku, metodę, która oblicza podatek od podanej ceny oraz metodę liczącą cenę całkowitą produktu. Chociaż jest to prosty przykład, widzimy, że kiedy tylko zmieni się sposób obliczania podatku to zmieni się także klasa Product. Ponadto wysokość podatku jest zależna od państwa, wysokości ceny, a nawet od kategorii produktu. 

Chcąc doprowadzić kod do zgodności z zasadą SRP (Single Responsibility Principle) możemy utworzyć osobną klasę TaxCalculator, która będzie zawierała prywatne pole typu Product i która będzie obliczać wysokość podatku w zależności od danego kraju, określonego w polu typu Product. W ten sposób, w przypadku zmiany wielkości podatku lub sposobu jego obliczania, unikniemy zmieniania klasy Product. 

Product.java

package online.shop;

public class Product {
    private String name;
    private double price;
    private Country country;

    public Product(String name, double price, Country country) {
        this.name = name;
        this.price = price;
        this.country = country;
    }

    public double getPrice() {
        return price;
    }

    public Country getCountry() {
        return country;
    }
}

TaxCalculator.java

package online.shop;

public class TaxCalculator {

    private Product product;

    public TaxCalculator(Product product) {
        this.product = product;
    }

    public double calculateTax() {
        switch (product.getCountry()) {
            case UK:
                return product.getPrice() * 0.12;
            case DE:
                return product.getPrice() * 0.11;
            case PL:
                return product.getPrice() * 0.10;
            default:
                return 0.00;
        }
    }

    public double getTotalPrice() {
        return product.getPrice() + calculateTax();
    }
}

Country.java

package online.shop;

public enum Country {
    UK, DE, PL;

}

Main.java


import online.shop.Product;
import online.shop.TaxCalculator;
import online.shop.Country;

public class Main {

    public static void main(String[] args) {
        Product productInUK = new Product("tableware", 12500.50, Country.UK);
        Product productInPL = new Product("tableware", 12500.50, Country.PL);
        double totalPriceInUK = new TaxCalculator(productInUK).getTotalPrice();
        double totalPriceInPL = new TaxCalculator(productInPL).getTotalPrice();
        System.out.println("Total price in UK: " + totalPriceInUK);
        System.out.println("Total price in PL: " + totalPriceInPL);
    }

}

PODSUMOWANIE

Tak więc, pierwsza z zasad SOLID to zasada jednej odpowiedzialności – Single Responsibility Principle. Mówi ona o tym, że każda klasa powinna mieć tylko jedną odpowiedzialność, jeden powód do istnienia. Nie powinno być także więcej niż jednego powodu do modyfikacji klasy. Powyższy przykład ilustruje zastosowanie tej zasady.