---
title: Принципы и паттерны программирования
seo:
  title: Принципы и паттерны программирования — QA
  description: "Тема «Принципы и паттерны программирования» для собеседования QA. Что такое SOLID? Приведите примеры. Что такое DRY, KISS, YAGNI?"
---

[Все темы QA](/qa)

## <strong>Что такое</strong> <code>SOLID</code><strong>? Приведите примеры.</strong> [#q-14bee738d69b81b08a9bce7bcd73113a]

<code>SOLID</code> — это акроним, обозначающий пять основных принципов
объектно-ориентированного программирования и дизайна, сформулированных Робертом
Мартином (Uncle Bob).

Описание каждого принципа с примерами&#58;

{/* prettier-ignore */}
1. <strong>Принцип единственной ответственности (Single Responsibility Principle,</strong> <code>SRP</code><strong>)</strong>&#58;

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

    - Пример&#58; Класс <code>Customer</code> должен отвечать только за данные и операции, связанные с клиентом, но не за логирование или базу данных.

1. <strong>Принцип открытости/закрытости (Open/Closed Principle,</strong> <code>OCP</code><strong>)</strong>&#58;

    - Программные сущности (классы, модули, функции) должны быть открыты для расширения, но закрыты для модификации.

    - Пример&#58; Использование интерфейсов и абстрактных классов для расширения функциональности, не изменяя существующий код.

1. <strong>Принцип подстановки Барбары Лисков (Liskov Substitution Principle,</strong> <code>LSP</code><strong>)</strong>&#58;

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

    - Пример&#58; Если для работы требуется класс <code>Shape</code>, то любой его подтип (например, <code>Circle</code>, <code>Rectangle</code>) должен работать корректно без изменений в коде, который использует <code>Shape</code>.

1. <strong>Принцип разделения интерфейса (Interface Segregation Principle,</strong> <code>ISP</code><strong>)</strong>&#58;

    - Клиенты не должны зависеть от интерфейсов, которые они не используют. Большие интерфейсы следует разделять на более маленькие и специфичные.

    - Пример&#58; Имеется интерфейс <code>Document</code>, который предоставляет методы для чтения и записи документов. Классы, не имеющие необходимости в записи, не должны реализовывать методы записи.

1. <strong>Принцип инверсии зависимостей (Dependency Inversion Principle,</strong> <code>DIP</code><strong>)</strong>&#58;

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

    - Пример&#58; Использование интерфейсов для взаимодействия между компонентами приложения, что позволяет легко заменять реализации интерфейсов без изменения клиентского кода.

Эти принципы помогают создавать гибкие, расширяемые и легко поддерживаемые системы, снижая связанность между компонентами и улучшая их управляемость.

:::note[Ссылки для изучения]

1. [Что такое SOLID](https://nuancesprog.ru/p/18651/#:~:text=SOLID%20%E2%80%94%20%D1%8D%D1%82%D0%BE%20%D0%BD%D0%B0%D0%B1%D0%BE%D1%80%20%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D1%85,responsibility%20principle%20%28%C2%AB%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF%20%D0%B5%D0%B4%D0%B8%D0%BD%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9%20%D0%BE%D1%82%D0%B2%D0%B5%D1%82%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D0%B8%C2%BB%29)
   :::

---

## <strong>Что такое</strong> <code>DRY</code><strong>,</strong> <code>KISS</code><strong>,</strong> <code>YAGNI</code><strong>?</strong> [#q-14bee738d69b811997d0e8b68dee100f]

Описание каждого из этих принципов&#58;

{/* prettier-ignore */}
1. <code>DRY</code> <strong>(Don't Repeat Yourself)</strong>&#58;

    - Принцип программирования, направленный на избегание повторения кода.

    - Основная идея заключается в том, чтобы каждая часть знаний (например, функции, классы, модули) должна иметь одну и только одну представляющую себя версию во всей системе.

    - Пример&#58; Использование функций или классов для избегания дублирования одинаковых блоков кода.

1. <code>KISS</code> <strong>(Keep It Simple, Stupid)</strong>&#58;

    - Принцип, согласно которому системы должны быть созданы настолько просто, насколько это возможно, без излишних сложностей.

    - Основная идея&#58; простота решений обеспечивает их легкость в понимании, разработке и поддержке.

    - Пример&#58; Предпочтение простым и понятным алгоритмам и структурам данных перед сложными и трудно поддерживаемыми.

1. <code>YAGNI</code> <strong>(You Aren't Gonna Need It)</strong>&#58;

    - Принцип, утверждающий, что не следует включать функциональность в программное обеспечение до тех пор, пока она не станет абсолютно необходимой.

    - Основная идея&#58; избегать создания излишне сложных и избыточных функций, которые могут быть никогда не использованы.

    - Пример&#58; Отказ от добавления функций "на всякий случай" или "для будущего использования", если нет явных и текущих потребностей.

Эти принципы помогают разработчикам создавать более эффективное, легко поддерживаемое и понятное программное обеспечение, сосредотачиваясь на его простоте, минимизации повторений и избегании излишней функциональности.

:::note[Ссылки для изучения]

1. [Основные прицнипы для разработки](https://habr.com/ru/companies/itelma/articles/546372/)
   :::

---

## <strong>Какие паттерны</strong> <code>GOF</code> <strong>вам известны? Приведите примеры их использования.</strong> [#q-14bee738d69b8109b284cdeaf72b939a]

Паттерны проектирования <code>GOF</code> (Gang of Four) — это основные шаблоны проектирования, описанные в книге "Design Patterns&#58; Elements of Reusable Object-Oriented Software". Вот некоторые из них с примерами использования&#58;

{/* prettier-ignore */}
1. <strong>Фабричный метод (</strong><code>Factory Method</code><strong>)</strong>&#58;

    - Определяет интерфейс для создания объекта, но оставляет подклассам решение, какой класс инстанциировать.

    - Пример&#58; базовый Dialog объявляет метод createButton(), а WindowsDialog и WebDialog переопределяют его, создавая разные реализации Button. Calendar.getInstance() является статическим фабричным методом и не демонстрирует этот механизм переопределения.

1. <strong>Абстрактная фабрика (</strong><code>Abstract Factory</code><strong>)</strong>&#58;

    - Предоставляет интерфейс для создания семейств взаимосвязанных или зависимых объектов без указания их конкретных классов.

    - <strong>Пример</strong>&#58; Создание GUI компонентов (кнопок, текстовых полей) в зависимости от операционной системы (Windows или macOS) с использованием различных фабрик.

1. <strong>Одиночка (</strong><code>Singleton</code><strong>)</strong>&#58;

    - Гарантирует, что класс имеет только один экземпляр, и предоставляет глобальную точку доступа к этому экземпляру.

    - Пример&#58; один экземпляр конфигурации приложения с контролируемой точкой доступа. Нужно учитывать потоки, тестирование и жизненный цикл; глобальный доступ не всегда удачен.

1. <strong>Строитель (</strong><code>Builder</code><strong>)</strong>&#58;

    - Разделяет процесс создания сложного объекта на несколько шагов, позволяя конструировать объект пошагово.

    - <strong>Пример</strong>&#58; Построение объекта <code>StringBuilder</code> в Java для динамической конкатенации строк с использованием методов <code>append&#40;&#41;</code>.

1. <strong>Декоратор (</strong><code>Decorator</code><strong>)</strong>&#58;

    - Динамически добавляет объектам новые обязанности, оборачивая их в объекты-декораторы.

    - <strong>Пример</strong>&#58; Расширение функциональности базового объекта, добавляя дополнительные возможности, такие как шифрование или сжатие данных.

Эти паттерны являются основой для создания гибких, расширяемых и поддерживаемых объектно-ориентированных систем, обеспечивая повторное использование кода и упрощение разработки сложных приложений.

:::note[Ссылки для изучения]

1. [Примеры паттернов проектирования GoF](https://sky.pro/media/primery-patternov-proektirovaniya-gof-v-bazovyh-bibliotekah-java/)
   :::
