Страницы

Поиск по вопросам

четверг, 28 ноября 2019 г.

Что значит инкапсулировать?

#ооп


Начал читать книгу о паттернах. В ней постоянно встречаются предложения типа 


  инкапсулируйте то, что изменяется


Что значит инкапсулировать ? Слово инкапсуляция я понимаю как сокрытие данных о реализации
некоторых участков кода для повышения уровня абстракции. Но что означает инкапсулировать
до конца не ясно... В голову приходит мысль о том, что это процесс сокрытия данных
о реализации. Но мое представление не всегда совпадает с контекстом из книги...
    


Ответы

Ответ 1



В разработке ПО есть два схожих понятия – инкапсуляция и сокрытия информации. Кто-то считает, что это синонимы, кто-то нет, но это не так и важно. Немного истории: Дэвид Парнас в году эдак 70-м в статье “On the Criteria To Be Used in Decomposing Systems into Modules” впервые ввел понятие сокрытия информации, как ключевого инструмента проектирования. Звучал этот принцип примерно так: декомпозиция системы на модули не должна основываться на анализе блок схем или потоков исполнения. Вместо этого, каждый модуль должен прятать внутри некоторое решение (design decision), предоставляя минимальное количество информации о нем своим клиентам. Вот небольшой пример. Допустим, вы разрабатываете ынтырпрайз приложение, которое делает что-то важное. Любое нормальное приложение обычно требует некоторой конфигурации: ну, параметры подключения к БД или серверу, и другую ценную информацию. И вот, матерый артихектор (*) вместе с не менее матерым клиентом просят прочитать конфигурацию из конфигурационного файла. (*) это не опечатка, пожалуйста, не правьте это! В процессе разговора с ними вы понимаете, что никто толком не знает, почему читать конфигурацию нужно именно из файла, какой должен быть у него формат и что именно там должно храниться. Теперь вы становитесь перед выбором: вы можете «размазать» сведения о конфигурации ровным слоем по всему приложению. Каждый компонент, которому нужны некоторые параметры, сам полезет в app config, вытянет оттуда нужные данные, пропарсит xml или json и будет готов служить. С другой стороны, очевидно, что решение о том, где именно хранится конфигурация и в каком формате, может измениться в будущем. Поэтому более вменяемым решением будет скрыть информацию о местоположении и формате конфигурации в одном модуле, например, с помощью классов Configuration и ConfigurationProvider. В этом случае, когда (да, именно, «когда», а не «если») требования изменятся, то поменяется лишь реализация класса ConfigurationProvider, а все остальные пользователи этого класса или конфигурации останутся неизменными. Аналогично, при изменении формата, поменяется тоже только процесс парсинга, а не потребители конфигурации. Этот пример кажется надуманным, но это не так! Мы довольно часто сталкиваемся с изменчивостью требований, но используем, к сожалению, один из двух подходов: • Полностью игнорируем возможность изменения требований и делаем все в лоб или • Создаем супер сложное решение с десятком уровней косвенности, которое должно выдержать изменения требований в любом направлении без изменения кода вообще. Более же разумный подход находится где-то по середине. Каждый раз, когда я начинаю разработку некоторой фичи, я думаю, сколько кусков в коде придется поменять, если требования или детали реализации существенно изменятся. При этом я не стараюсь свести количество изменений к 1 (ну, типа, если мы следуем SRP, то должно быть только одно место, в случае изменения требованй). Я стараюсь, чтобы этих мест было мало, а изменения были простыми. Собственно, это и есть суть information hiding и его младшей сестры – инкапсуляции.

Ответ 2



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

Ответ 3



Инкапсулировать - значит скрывать. Идея инкапсуляции состоит в том, что вы скрываете реализацию ваших классов от пользователей(и программистов), предоставляя им для работы интерфейсы ваших классов. Также это подразумевает скрытие данных при помощи идентификаторов доступа(public, private, protected). Например вы программист, и вам дают доступ к библиотеке. А именно, вы подключаете некий заголовочный файл, с доступом к интерфейсам некоторых классов, и манипулируете с объектами этого класса, через методы этого класса. Это исключает возможность повреждения рабочего кода. Как то так...

Ответ 4



Есть метод делатьСэндвич();. Реализация может быть очень изменчива: добытьХлеб ржаной белый хлебРакфор прожарить? мякиш корочка ... Это только добыча основы. Неполная версия. Поэтому скрыть (инкапсулировать, как говорит нынче молодёжь) это стоит как минимум по двум причинам: Не пугать конечного пользователя интерфейсом таким разнообразием, ибо пугающе это и ему знать не нужно (простота - залог используемости). Чтобы случайно и/или намеренно не повредить логику работы сэндвичного завода.

Комментариев нет:

Отправить комментарий