# Инкапсулируйте не только состояние, но и поведение

(В оригинале - Encapsulate Behavior, not Just State)

В теории систем инкапсуляция является одной из наиболее часто используемых конструкций, когда речь заходит о больших и сложных системах. В индустрии ПО ценность инкапсуляции также хорошо осознаваема. Инкапсуляция поддерживается языками программирования наравне с функциями, модулями и пакетами.

Модули и пакеты инкапсулируют большие объемы и системы, а классы и функции – более тонкие аспекты. В течении многих лет я сталкиваюсь с тем, что именно классы являются самым проблемным местом для правильного использования инкапсуляции. Весьма часто можно увидеть класс, в котором присутствует единственный метод длиной в 3000 строк, или же класс, в котором реализованы лишь set() и get() методы для каждого атрибута. Эти примеры показывают, что разработчики не до конца понимают объектно-ориентированную модель, теряя возможность использовать всю ее мощь.

Объект инкапсулирует и состояние, и поведение, причем поведение зависит от актуального состояния. Представьте себе объект «Дверь». У него будет четыре состояния: «Открыто», «Закрыто», «Открывается», «Закрывается». И у него будет две операции: «Открыть» и «Закрыть». В зависимости от состояния, методы «Открыть» и «Закрыть» будут работать по-разному.

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

То, как это работает на практике, проще всего показать на примере. Пусть, например, у нас есть три класса: Customer, Order и Item. Объект Customer – естественное место для инкапсулирования кредитного лимита и правила его проверки. Объект Order знает об ассоциированном Customer, и его метод addItem делегирует саму проверку ему, вызывая `customer.validateCredit(item.price())`. Если условие не выполняется, генерируется исключение и покупка не выполняется.

Менее опытный ООП-разработчик может сделать по-другому – собрать все бизнес-правила в отдельный объект `OrderManager` (или `OrderService`). В таком дизайне `Order`, `Customer`, и `Item` рассматриваются лишь как набор данных. Вся логика же вынесена из них и сосредоточена в большом методе класса `OrderManager`, с большим количеством ветвей и условий внутри. Такие методы очень легко «сломать» и почти невозможно поддерживать. Причина? Нарушенная инкапсуляция.

Подведя итог: не нарушайте инкапсуляции и используйте свойства языка для ее поддержки.

Автор оригинала - [Einar Landre](http://programmer.97things.oreilly.com/wiki/index.php/Einar_Landre)


---

# Agent Instructions: 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://97-things-every-x-should-know.gitbook.io/97-things-every-programmer-should-know/ru/thing_20.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.
