← Назад к вопросам

Что обозначает аббревиатура SOLID?

1.0 Junior🔥 251 комментариев
#SOLID и паттерны проектирования

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI21 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# SOLID принципы

SOLID это акроним пяти основных принципов объектно-ориентированного дизайна, которые помогают писать более гибкий, модульный и понятный код.

S - Single Responsibility Principle (Принцип единственной ответственности)

Класс должен иметь только одну причину для изменения. Один класс - одна ответственность.

// Плохо: класс делает слишком много
public class User {
    private String name;
    private String email;
    
    public void saveToDatabase() { }      // БД
    public void sendEmail() { }           // email
    public void logActivity() { }         // логирование
    public void generateReport() { }      // отчёты
}

// Хорошо: разделили ответственности
public class User {
    private String name;
    private String email;
}

public class UserRepository {
    public void save(User user) { }
}

public class EmailService {
    public void sendEmail(User user) { }
}

public class ActivityLogger {
    public void log(String activity) { }
}

O - Open/Closed Principle (Принцип открытости/закрытости)

Класс должен быть открыт для расширения, но закрыт для модификации.

// Плохо: нужна модификация при добавлении нового типа
public class PaymentProcessor {
    public void process(String paymentType, double amount) {
        if (paymentType.equals("creditCard")) {
            // логика для кредитки
        } else if (paymentType.equals("paypal")) {
            // логика для paypal
        }
        // Новый тип платежа? Нужно изменить класс!
    }
}

// Хорошо: расширяется без изменения
public interface PaymentMethod {
    void process(double amount);
}

public class CreditCardPayment implements PaymentMethod {
    public void process(double amount) { }
}

public class PayPalPayment implements PaymentMethod {
    public void process(double amount) { }
}

public class PaymentProcessor {
    private PaymentMethod paymentMethod;
    
    public void process(double amount) {
        paymentMethod.process(amount);  // работает для любого типа
    }
}

L - Liskov Substitution Principle (Принцип подстановки Лисков)

Объекты подклассов должны корректно заменять объекты базовых классов.

// Плохо: нарушение контракта
public class Bird {
    public void fly() { }
}

public class Penguin extends Bird {
    public void fly() {
        throw new UnsupportedOperationException("Penguin cannot fly");
    }
}

// Клиент ожидает что все птицы летают
Bird bird = new Penguin();
bird.fly();  // Exception!

// Хорошо: правильная иерархия
public abstract class Bird { }

public class FlyingBird extends Bird {
    public void fly() { }
}

public class Penguin extends Bird {
    public void swim() { }
}

I - Interface Segregation Principle (Принцип разделения интерфейса)

Клиент не должен зависеть от методов, которые он не использует.

// Плохо: большой интерфейс
public interface Worker {
    void work();
    void eat();
    void sleep();
}

public class Robot implements Worker {
    public void work() { }
    public void eat() { throw new UnsupportedOperationException(); }
    public void sleep() { throw new UnsupportedOperationException(); }
}

// Хорошо: разделили интерфейсы
public interface Workable {
    void work();
}

public interface Eatable {
    void eat();
}

public interface Sleepable {
    void sleep();
}

public class Robot implements Workable {
    public void work() { }
}

public class Human implements Workable, Eatable, Sleepable {
    public void work() { }
    public void eat() { }
    public void sleep() { }
}

D - Dependency Inversion Principle (Принцип инверсии зависимостей)

Должны зависеть от абстракций, а не от конкретных реализаций.

// Плохо: зависимость от конкретного класса
public class EmailService {
    private SmtpServer smtpServer = new SmtpServer();  // конкретный класс
    
    public void sendEmail(String email) {
        smtpServer.send(email);
    }
}

// Хорошо: зависимость от интерфейса
public interface MailServer {
    void send(String email);
}

public class EmailService {
    private MailServer mailServer;  // абстракция
    
    public EmailService(MailServer mailServer) {
        this.mailServer = mailServer;  // инжекция зависимостей
    }
    
    public void sendEmail(String email) {
        mailServer.send(email);
    }
}

public class SmtpServer implements MailServer {
    public void send(String email) { }
}

public class GmailServer implements MailServer {
    public void send(String email) { }
}

Примеры применения SOLID

Пример 1: Spring и SOLID

// S: UserService отвечает только за логику
@Service
public class UserService {
    private UserRepository repository;
    
    public User createUser(UserDTO dto) {
        return repository.save(new User(dto));
    }
}

// O: новый тип уведомления без изменения кода
public interface Notification {
    void send(String message);
}

public class EmailNotification implements Notification {
    public void send(String message) { }
}

public class SmsNotification implements Notification {
    public void send(String message) { }
}

// D: инжектируем зависимостью
@Service
public class NotificationService {
    private Notification notification;
    
    public NotificationService(Notification notification) {
        this.notification = notification;  // Spring инжектирует
    }
}

Преимущества SOLID

  • Легче тестировать (mock зависимости)
  • Легче модифицировать (меньше побочных эффектов)
  • Легче расширять (добавлять новые функции)
  • Легче понять (код более логичен)
  • Меньше багов (меньше связанности)

Вывод

SOLID это не правила, а принципы. Не применяй их слепо, но помни когда разрабатываешь. Правильное применение SOLID делает код более гибким, модульным и поддерживаемым. В Spring Framework и современной Java разработке SOLID это стандарт.

Что обозначает аббревиатура SOLID? | PrepBro