> For the complete documentation index, see [llms.txt](https://dev-ttf.gitbook.io/global-tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dev-ttf.gitbook.io/global-tech/osnovnoe/gaidy/principy-solid.md).

# Принципы SOLID

### [**Определение, примеры их нарушения и их исправление по SOLID**](https://metanit.com/sharp/patterns/5.1.php)

### **SOLID**

Термин "SOLID" представляет собой акроним для набора практик проектирования программного кода и построения гибкой и адаптивной программы. Данный термин был введен 15 лет назад известным американским специалистом в области программирования Робертом Мартином

Сам акроним образован по первым буквам названий SOLID-принципов:

* **S**ingle Responsibility Principle (Принцип единственной обязанности)
* **O**pen/Closed Principle (Принцип открытости/закрытости)
* **L**iskov Substitution Principle (Принцип подстановки Лисков)
* **I**nterface Segregation Principle (Принцип разделения интерфейсов)
* **D**ependency Inversion Principle (Принцип инверсии зависимостей)

### **Single Responsibility Principle**

**Принцип единственной обязанности** (Single Responsibility Principle) можно сформулировать так:\
**У класса должна быть только одна причина для изменения**\
Под обязанностью здесь понимается набор функций, которые выполняют единую задачу. Суть этого принципа заключается в том, что класс должен выполнять одну единственную задачу. Весь функционал класса должен быть целостным, обладать высокой связностью (high cohesion).

#### **Нарушение SRP**

Допустим в классе Report написано очень много разных способов вывести репорт пользователю. Если мы поменяем Text на какой-то метод, то нам придется править каждый из методов печати, т.к. они работали напрямую с Text. Это очень долго, да и сам класс получился очень большим, а в более сложных и реальных системах нарушение SRP может окончательно запутать программиста, если он решится что-то поменять в коде. Нарушение этого принципе не столько ограничивает программиста, сколько заставляет его писать лишний код по мере роста проекта, в котором легко запутаться

![](https://lh5.googleusercontent.com/vk74sNgnvX2-Kv6yLWiEQYrDi0HEXBv8CJ138mcthLKQmBURmIAQ8ADoAzoaxePR0dbsPlS2bsGJE_NmMGps7__7WH7p7O9TKQXUg8XnLxfaHcCKtxFlly8C0YC5-3EazSn4cxX3_bwGkpElxJijhJqWD0yGSF3O)![](https://lh4.googleusercontent.com/XSkT6EAKNue0XQ5vlz3DqhL0mCtYxw8y0YUMXJDbN8ngXu444o5JtKrJ_vCmVcHOzWpt8wlddExlf4jCcvUFU1ZMQa8SX9LiaqPd7DqDx-YXe5qZytkoZeK6PZNaiQRUuaa0wlYS5OslkuiDyjudLn2RqDc2DkeC)

#### **Применение SRP**

Проблему бесконечного наращивания и уменьшение его связанности можно решить созданием интерфейса IPrinter, и его реализацией в виде ConsolePrinter и FilePrinter. При применении SRP в начале будет казаться, что мы только усложняет код, и увеличиваем его в размерах, но по мере разработки проекта он не будет так сильно дальше усложнятся и разрастаться, по сравнению с кодом, который был написан без соблюдения SRP

![](https://lh3.googleusercontent.com/cgWmeuf-cnn6nJrxjdEtgAUBIz9rtpRQgHFXWGa_kbdrgoasMJrE3VupX1fE3OF9uMteJPlI-NDYYAR-TBlA9_TjXYa7tzO7JnKNoRX6P0uH0k4hoQ78mm7CyfttKoK0wTLR-RLdDJmiwj_18X_hUu3y9A8DjIpq)![](https://lh6.googleusercontent.com/KoczfBgTij8hv2EN07Ch3-Pe45yGEdsTF_YQa5PtqSoekAYuBmfev0MxNNA4SGWwhhP0V9MY66q2i0V3-ffJzkqXNJAIRumG3rv82JTDNd1YExuputD5wqAnvV41QMvv93ptQCXw6UbFz5WvB-zmh2ULFVTkBaoa)![](https://lh6.googleusercontent.com/t63TZxzBH6y0aRv75J7nptA_ti535ZSfnCJxQFd-KMZIb9A2MxkLGxCS4eLMY2s0RHxxlNEHO7cDt3ci0Ag48vL1gQYf-1G4a5hgEjQYDTqvOcoh6FZ1640pVR7smGcxpHAlZsMzazKXmypOcWmudj7pXf97OB0T)![](https://lh5.googleusercontent.com/5jK5-VbwAZeMy2x0lgekD6cc_LbgDDFttWOkAjbJFAaRvRZrLqQYNeeDVTLsfJRJpxLyfnNalgogKX7qts-m8EMKtQfpDn90LXTDyWmsdAgR3TzHLKFOu6BKdWdG3nMKjVNbSAFudWZnZNoPl0QFNphcTetv5lbm)![](https://lh4.googleusercontent.com/FIswmbpPJZXyML-HYa1bCKSDLHnakn4qUNmxSjGciO-LXmKufCBT1m4jI_zSTqd3NotUGCErhCX-L46UDx4da8davJ6T102gof7jq2bIJB1baeyX1erivE8bBUYfD41HzGn0kknMxW93XE2QnSbGPEFlOrBiVtl5)

### Open/Closed Principle

**Принцип открытости/закрытости** (Open/Closed Principle) можно сформулировать так:\
**Сущности программы должны быть открыты для расширения, но закрыты для изменения.**\
Суть этого принципа состоит в том, что система должна быть построена таким образом, что все ее последующие изменения должны быть реализованы с помощью добавления нового кода, а не изменения уже существующего, за исключением фикса багов и рефакторинга

### Liskov Substitution Principle

**Принцип подстановки Лисков** (Liskov Substitution Principle) представляет собой некоторое руководство по созданию иерархий наследования.\
В общем случае данный принцип можно сформулировать так:\
**Должна быть возможность вместо базового типа подставить любой его подтип.**

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

#### **Нарушение LSP**

Класс Square перестает быть квадратом, потому что подвергается некорректным изменением под видом обычного прямоугольника, которого наследует. Решение данной ситуации – не наследовать Square от Rectangle, а делать 2 разных класса

#### ![](https://lh3.googleusercontent.com/uaVschD9KWTHa8lRBBKl6PXFBfGiHEaQMwIcrU4QvJnfanqZ8bXW6W5E6UKvNjMzbNVgK-qBwEBmO5TL8Ww_UnMXqo4jKbQa5P4pt2k-tohVrV5C84xQ-2xMW5Jrja7lGlBMxAF_IQtqeeXwBXbNedOSBodfb8ps)![](https://lh5.googleusercontent.com/wyeRRzBH6tMDCL2akZWtx-SdVOU0-usQoNG6L9bZLz8g4eAFHouHZ4Qem1weC5re20zHaFBKpvzIsoE93IYYHnjpK5mRCk5FwfUIW9hv7yh4xrQ9xiLUy0XzYdU0vt_EPAAh02geo1HY4R7JhGoeTxyQndzTBoTM)<br>

<div align="center"><img src="https://lh6.googleusercontent.com/MjA3e34tBCPl8Cc2Z0vfjHlJjYqsuCK3zaeuaBhIb020FMV-Bd9ZgMPuFpx4DlLLDefaG1ZjL-e7NRyOuLHdoO8Y3wpu_xey_AgU2T_k72tLDrQ-XbrXCQjT6gF_P8G4jc0Ouzs0EQbC7zPH9bV5e0CW6MunowoN" alt=""></div>

### **Interface Segregation Principle**

**Принцип разделения интерфейсов** (Interface Segregation Principle) относится к тем случаям, когда классы имеют "жирный интерфейс", то есть слишком раздутый интерфейс, не все методы и свойства которого используются и могут быть востребованы. Таким образом, интерфейс получатся слишком избыточен Принцип разделения интерфейсов можно сформулировать так:\
**Клиенты не должны вынужденно зависеть от методов, которыми не пользуются.**\
При нарушении этого принципа клиент, использующий некоторый интерфейс со всеми его методами, зависит от методов, которыми не пользуется, и поэтому оказывается восприимчив к изменениям в этих методах. В итоге мы приходим к жесткой зависимости между различными частями интерфейса, которые могут быть не связаны при его реализации.

#### **Нарушение ISP**

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

![](https://lh3.googleusercontent.com/lTkox6cU1gT2vynlbPu8krgNhJwnIJsm7CB_zmmugjlUO08TOYteTqNJqcEfocGrlPdamAhadPlCrAK48MPzhaXk7ghnLHa4WsAtvDMbedRUprLNoSw-zqYDTKGt5sxnJ_JMg4ZAT1PkCku2HayC-yE9zt8ggUIA)![](https://lh5.googleusercontent.com/Y8v2TTtRc9YbkyxEyNU4ldj1GHJir5GXQs-pts2IpSEsjrZ_Xp7XoMxullwQY9PyVqLg8snxAuKdBOuzJUR18KM4VbeyspzzK4m4NmZnyaP34c1pd0wF6IONMGcsPcp3fY-_Zy3a7-pqdYdsWAQYxfNvyoo9tFmb)

#### **Применение ISP**

![](https://lh5.googleusercontent.com/uk8PwIeqYkfVSJ8EJb8lkIG18hGtfAL7Cy5SGJ_VJegmoTCbdZzRPr1GFOVXV0a_LwjmBJ4TRU4uGWKKmX3Pu-Xlg-3aY3PUT6KQshX5xaSgUoOh2VXulTOyBvL2uQyLfh9pxObymuiNDVQJVqRiarJg95ruZzbN)![](https://lh5.googleusercontent.com/0JyEVB0sZ0mANhwyc6cm50zOsZJzccNmG4uJomYt9VEfaztCxXLsbIr6HPAEdTqtR9n2z4sBdsPhOhh99mm90n9Pi9_sw8A7weI5DviAahLbHGMs-C2g98b97M-FboHmK42jnqr_sXM1hMDly8K0R8n1kuLvnZm2)![](https://lh3.googleusercontent.com/QHxY9tRbdeh6DxyAOpb4T66MC7TgmlDl0qstoFq0Qmv1yowTJ6LbOK1Q5aoP4eRMaX8snGWVZ0Ec0wNIjuyCbhpz00sT-KxuO4kMU1wjOvo7VUXMqK_7Rg2iNHTriUZA6ASdC3tVVQe2mFRLfOG34SC0tloFzIvy)![](https://lh4.googleusercontent.com/Nver6EYJaeup82-XPX6PkLkmvOtW5KkSXWF12j6gCvOu1OHfP5vwVnkgpwR-w27Mw1GRHltAmgpDXBC-wlNcUJVd2scq4MyaQLoGVzL7oeGvo7P8b3gMZR15k9feHYezmaCyN8rc_NnS-4CAMpKzJeppm1WfZi-o)<img src="https://lh6.googleusercontent.com/GAS4EmvTh3IOMvOkLFQ_q6FD6_IZVkJoViIHuoCJWe66moug4SMU_KAqIQmGZ6482bnf7lqCbCCeC04nHXP2Qcz03KG8MEj8T_AcIM5qKRa7YQIO3NJViGulC_UIXreMIVcwC5W7cpwDaNMxMmDgrgFCGPurYWhw" alt="" data-size="original">

### Dependency Inversion Principle

**Принцип инверсии зависимостей** (Dependency Inversion Principle) служит для создания слабосвязанных сущностей, которые легко тестировать, модифицировать и обновлять. Этот принцип можно сформулировать следующим образом:

**Классы верхнего уровня не должны зависеть от классов нижнего уровня. И те и другие должны зависеть от абстракций. Абстракции не должны зависеть от деталей класса. Детали класса должны зависеть от абстракций.**

#### **Нарушение DIP**

![](https://lh3.googleusercontent.com/Cg7f-bKkFt9ebN6c4e2sxZl4yTgaAPkoA2v6_aNNyu2tOANhc5ErgNLY8-gVz95c6EwbDCioPbiMOf61HCgK3NMAESSRQjC8t-zVj-4rWcvALv12bbLdgcGJ2Tgbh5S1AcrkZLi7NezYoMgpjmBKS7kjaWeDjwvI)

**Класс Book, представляющий книгу, использует для печати класс ConsolePrinter. При подобном определении класс Book зависит от класса ConsolePrinter. Более того мы жестко определили, что печать книгу можно только на консоли с помощью класса ConsolePrinter**

#### **Использование DIP**

![](https://lh3.googleusercontent.com/oEYHNrNf-S4yXboUgMmKjLxevp8_W40y4oVbWG-jYrEyshXhM_S9xWftkSxftjQrzdF5LUZPiNK9Z_PdBSc47nFDQn16TSfViipCy0WjFYAqBpLN1_f5D4qSbmUrMEcQpMafYDA801yd37dneg-RUbHmFTJc00YT)

Конкретную реализацию можно представить как абстракцию (интерфейс), и уже работать только с ней

![](https://lh6.googleusercontent.com/ZEoL1j4DRlOcc2QSZ6Ex3CHWhpq_8U4eSBQtqx1CoF1B0o2Kicw_T2Cj5CqtCI3etvzVfVwl3zAoxjZqWhl-sqzPqfinCV7UtF02qDCJ8JR5L3qokztB3pCzxn-2SUPsPJDFUeC_3ZdYIlNDOzxKlYIodmDEQGXG)

Таким образом мы можем реализовывать конкретные классы на основании сделанной абстракции


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dev-ttf.gitbook.io/global-tech/osnovnoe/gaidy/principy-solid.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
