Что такое SOLID? Приведите примеры.qa-38

Что такое SOLID?

SOLID - это 5 принципов объектно-ориентированного программирования, которые делают код более понятным, гибким и поддерживаемым.

Расшифровка принципов

1. Single Responsibility Principle

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

Пример нарушения:

class User {
    void saveToDatabase() { /*...*/ }
    void sendEmail() { /*...*/ }
    void validate() { /*...*/ }
}

Исправленный вариант:

class User {
    // только данные пользователя
}

class UserValidator {
    void validate(User user) { /*...*/ }
}

class UserRepository {
    void save(User user) { /*...*/ }
}

class EmailService {
    void sendEmail(User user) { /*...*/ }
}

2. Open-Closed Principle

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

Пример:

interface ReportGenerator {
    String generate();
}

class PdfReport implements ReportGenerator {
    public String generate() { /*...*/ }
}

class HtmlReport implements ReportGenerator {
    public String generate() { /*...*/ }
}

Польза для QA: Можно добавлять новые типы отчетов без изменения существующего кода.

3. Liskov Substitution Principle

Подклассы должны быть заменяемыми на свои базовые классы.

Пример нарушения:

class Bird {
    void fly() { /*...*/ }
}

class Penguin extends Bird {
    // Пингвины не летают!
    void fly() {
        throw new UnsupportedOperationException();
    }
}

Исправленный вариант:

class Bird {
}

class FlyingBird extends Bird {
    void fly() { /*...*/ }
}

class Penguin extends Bird {
    // Теперь корректно
}

4. Interface Segregation Principle

Много специализированных интерфейсов лучше одного универсального.

Пример нарушения:

interface Animal {
    void eat();
    void fly();
    void swim();
}

Исправленный вариант:

interface Eater {
    void eat();
}

interface Flyer {
    void fly();
}

interface Swimmer {
    void swim();
}

5. Dependency Inversion Principle

Зависимости должны строиться на абстракциях, а не на конкретных реализациях.

Пример:

interface Database {
    void save(User user);
}

class UserService {
    private Database database;

    public UserService(Database database) {
        this.database = database;
    }
}

Польза для QA: Легко подменять реальную БД на mock в тестах.

Практическое применение в тестировании

1. Для автотестов

- SRP: Разделение тестовых классов по функционалу
- OCP: Возможность добавлять новые тесты без изменения базовых классов
- DIP: Внедрение зависимостей для мокирования

2. Для анализа кода

- LSP: Проверка корректности иерархий классов
- ISP: Анализ "жирных" интерфейсов

Пример SOLID-автотеста

// SRP: Отдельный класс для тестов логина
class LoginTest {
    // DIP: Внедрение зависимости
    private LoginPage loginPage;

    @BeforeEach
    void setup(WebDriver driver) {
        // OCP: Базовый setup можно расширять
        loginPage = new LoginPage(driver);
    }

    // ISP: Тест проверяет только одну функциональность
    @Test
    void validLoginTest() {
        loginPage.login("user", "pass");
        assertTrue(loginPage.isLoggedIn());
    }
}

Резюмируем

SOLID в QA помогает:

  1. Писать более поддерживаемые автотесты
  2. Лучше понимать архитектуру тестируемого приложения
  3. Эффективнее коммуницировать с разработчиками

Основные принципы:

  1. SRP - одна ответственность
  2. OCP - расширение без модификации
  3. LSP - корректное наследование
  4. ISP - узкоспециализированные интерфейсы
  5. DIP - зависимости от абстракций

Понимание SOLID критично для:

  • Анализа качества кода
  • Написания гибких тестовых фреймворков
  • Проведения технических собеседований
  • Участия в code review