Pull to refresh

Comments 71

Подлинное назначение инкапсуляции — собрать в одном месте знания, относящиеся к устройству некой сущности, правилам обращения и операциям с ней.

Откуда вы берете "подлинность" этого назначения, и почему вы считаете, что определение, данное, скажем, в вики — менее "подлинное"?

Очень правильный вопрос.

Для начала встречный вопрос: вы согласны, что размазывание деталей реализации по всему коду — это плохо?

Второй вопрос: вы согласны, что значение термина — это вопрос договорённости?

Теперь мой ответ.

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

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

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

P.S.
Определения терминов из мира программирования формируются исходя из работ авторитетных товарищей из этого мира программирования. Между тем, товарищи Роберт Мартин и Мартин Фаулер не намного умнее нас с вами, просто они пишут книги, а мы — нет. Поэтому я предлагаю нам с вами тоже сделать свой вклад в улучшение мира программирования. Например, путём корректировки некоторых не очень хороших определений терминов на определения, которые приведут в конечном итоге к созданию более качественного кода каждым программистом.
вы согласны, что размазывание деталей реализации по всему коду — это плохо?

Да (обычно).


вы согласны, что значение термина — это вопрос договорённости?

Да.


Я считаю, что определение в вики хуже, потому что оно не ведёт прямиком к полезному эффекту сокрытия реализации.

Это очень странно, учитывая, что там явно написано про "information-hiding mechanism".


Впрочем, ваше определение тоже не ведет к полезному эффекту сокрытия реализации.


Более того, вы приравниваете "сокрытие реализации " к "неразмазыванию функциональности", хотя это не одно и то же.


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

И это правило не обязательно будет инкапсуляцией, вот что важно.


Фактически, определение из вики — это частный случай моего определения

Нет. Ваше определение слишком размыто (до невыполнимости) в части information hiding.


Определения терминов из мира программирования формируются исходя из работ авторитетных товарищей из этого мира программирования.

И из консенсуса в сообществе.


Между тем, товарищи Роберт Мартин и Мартин Фаулер не намного умнее нас с вами,

У вас нет оснований для этого утверждения.


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

Для этого надо сначала определиться, какое определение "более хорошее". Я вот ваше "более хорошим" не считаю.

А зачем брать существующий термин с точным значением и пытаться его поменять? Что мешает придумать новый термин с нужным вам значением и использовать его?

Мне не нравится определение из вики:
Инкапсуляция (англ. encapsulation, от лат. in capsula) — в информатике упаковка данных и функций в единый компонент.


Оно слишком водянистое, недостаточно точное и вообще не раскрывает сути, которая используется при назывании четырех китов ООП. Ну вот, к примеру:
То есть если упаковать все-все данные и функции в единый компонент — это будет инкапсуляция? Если это данные из разных предметных областей? То есть если я в одном компоненте опишу деньги на счете пользователя и количество сообщение на форуме, то, согласно этому определению, это будет инкапсуляция, но по духу, по моему мнению, это как раз будет нарушение инкапсуляции.

Чтобы этот термин был более корректным — ему необходимо как минимум добавить описание данных и функций, которые могут объединятся в одном компоненте. То есть
Инкапсуляция (англ. encapsulation, от лат. in capsula) — в информатике упаковка данных и функций (которые обладают определенным свойством) в единый компонент.


Я понимаю, что с моими замечаниями инкапсуляция уже начинает набирать признаков SRP, но он близок по сути и к принципу сокрытия и к принципу абстракции.

Там ниже есть "подробности":


языковая конструкция, позволяющая связать данные с методами, предназначенными для обработки этих данных.
Жаль, что этой подробности нету в определении. И жаль, что туда также добавляют совершенно (по моему) некорректный пассаж о сокрытии данных.

То есть, более правильное определение будет такое:

Инкапсуляция (англ. encapsulation, от лат. in capsula) — в информатике упаковка данных и функций, предназначенных для обработки этих данных в единый компонент.


Так? Всё дело в том, чтобы можно было положить данные и функции для них в один класс/неймспейс/итд?

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

Не знаю, смог ли я объяснить, я чувствую, что аргументы мутные. Просто это из разряда: «чтобы язык был ООПшный — там должно быть ключевое слово class». Это не подходит для теоретиков, которые придумали принцип подстановки Барбары Лисков, это подходит для ребят, которые спорят за пивом в баре.
Теперь мне это определение кажется слишком мелким в качестве основополагающего принципа ООП.

А я (лично) и не считаю, что инкапсуляция — это "основополагающий принцип ООП". Для меня это всего лишь один из принципов, которые делают разработку легче/более поддерживаемой. И как раз привязки к ООП в понимании термина "инкапсуляция" я пытаюсь избегать.


PS Ну и отдельно я, на самом деле, пытаюсь избегать русской википедии, потому что англоязычные определения терминов часто лучше.

Но мы как раз спорим в контексте «определений из соответствующих предметных областей», а не в контексте «личного мнения». А в контексте современной Computer Science инкапсуляция является одним из основных принципов ООП
А в контексте современной Computer Science инкапсуляция является одним из основных принципов ООП

… но при этом не уникальна для ООП, про что явно написано в английской википедии.


Ну и на самом деле, тут есть очень интересный вопрос: а что такое "основной принцип"? Это принцип, без которого (ООП) не будет? Или принцип, который если есть, то ООП? Или что-то третье?


Вообще, чем дальше, тем интереснее найти, кто же конкретно ввел этот термин, и сказал, что "он основополагающий".

Эта ветка началась с вашего комментария:
Может все-таки стоит брать определение из соответствующей предметной области?

Я просто описал, почему считаю определение из предметной области сомнительным и согласен с идеей, что неплохо было бы над нам подумать, а вы, похоже, со мной согласны (как минимум, отчасти).

И как раз привязки к ООП в понимании термина «инкапсуляция» я пытаюсь избегать.

Да, я согласен. Мне нравится пример, который ниже привел автор статьи:

Правильно объединять деньги их округляя. То есть мы везде пишем:
const sum = round(amount1 + amount2);


Но это уже детали реализации, которые лишние каждый раз. Потому мы вводим функцию:
function add_money (amount1, amount2) {
  return round(amount1 + amount2);
} 


И этим инкапсулируем логику. Такое видение инкапсуляции мне кажется намного лучше, чем то, что описано в википедии:

1. Это реальное влияние на поддержку кода
2. Оно не зависит от парадигм — подходит и под ООП и под ФП и под ПП.
3. Оно никак не зависит от механик языка. То есть нам не нужны специфические языковые конструкции для соблюдения этого принципа (меня страшно выбешивает, когда люди считают модификатор private как-то связанным с инкапсуляцией)
4. Я верю, что это близко к аксиоме, что такой подход к коду полезен, в отличии от холиварного подхода с «методами и свойствами в одном классе».

С таким видением инкапсуляции этот принцип становится реально теоретическим и полезным, но, увы, я недостаточно образован, чтобы это видение формализовать. Может вы сможете помочь?
Только вот IRL люди отказываются от инкапсуляции и переходят к anemic object. Что бы там не говорил Фаулер.
Вот разобрать причины перехода к anemic object было бы очень интересно.
Падение (средней) квалификации? ;)
Скорее, распространение всяких ORMов и REST-сервисов, а также популярность паттернов «модель-представление-фиговина с бизнес-логикой между ними».
Я тоже это отношу к к REST и сериализации. Мол, когда объекты стали активно сериализовывать/десериализовывать и мэпить они потеряли свою субъектность.

В значении:
(Субъектность — свойство индивида быть субъектом активности.)
Возможно, хотя и не факт. Скажем так, есть варианты (для сериализации в частности), которые не требуют, чтобы объект открывал свое устройство.
Тут даже дело не в открытии устройства, по сути практически все сериализаторы и так просто тянут данные из публичный свойств, игнорируя остальные. Это становится архитектурно неудобно. Гоняя через эти сервисы и прокси анемичные объекты, вы можете быть уверены, что состояние объекта на одной стороне и на другой идентично.
Если это объект, состояние которого определяется ещё и приватными свойствами, да ещё и с бизнес-логикой, то вы получите архитектурный косяк. В лучшем случае просто нарушение Single Responsibility, когда одна и та же сущность используется для двух совершенно разных задач. В худшем — проблему синхронизации состояний двух разных объектов.
Вот прямо идеальная формулировка.
Гонять через сервисы код вообще нехорошо и небезопасно. Поэтому сериализуемое состояние по большому счету обязано содержать только данные. Можно вспомнить хоть например сравнительно недавние CVE на тему apache commons collections.

>Если это объект, состояние которого определяется ещё и приватными свойствами, да ещё и с бизнес-логикой, то вы получите архитектурный косяк.
Если он сам себя сериализует/десериализует, теряя по дороге приватные свойства — то это его личные внутренние проблемы, разве нет? Ну да, согласен, архитектурно это косяк. Вполне себе очевидный — не надо было пихать бизнес логику в те объекты, которые могут путешествовать по сервисам или тем более передаваться по сети.

Но из этого совершенно не следует, что все объекты должны быть только такими.
Но из этого совершенно не следует, что все объекты должны быть только такими.

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

Когда вы противопоставляете инкапсуляцию анемичным объектам, вы имеете в виду только одно из (как минимум) двух возможных значений понятия "инкапсуляция".


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

Anemic не исключает сокрытия реализации = инкапсуляции, хоть данные и помещаются отдельно от функций. Раз есть тенденция к популяризации anemic — значит, для кого-то это имеет смысл. Значит, инкапсуляция в смысле википедии не так уж и хороша, раз ей пренебрегают.

Да, мне тоже любопытно понять, почему anemic набирает популярность. Думаю, у её приверженцев есть достаточно сильные аргументы.
Раз есть тенденция к популяризации anemic — значит, для кого-то это имеет смысл. Значит, инкапсуляция в смысле википедии не так уж и хороша, раз ей пренебрегают.

Моё ИМХО — это просто другой подход. Не лучше и не хуже, продуктивность разработки и сопровождения не слишком отличается в обоих случаях. Тенденции в ИТ подвержены моде точно так же, как и в одежде. Выкатил кто-то известный новый гайдлайн по разработке — и падкий до новых блестящих штук народ массово кидается юзать. Тем более что новые технологии и клиентам продаются лучше зачастую просто потому, что новые.
Да, мне тоже любопытно понять, почему anemic набирает популярность. Думаю, у её приверженцев есть достаточно сильные аргументы.

Мое мнение, anemic модели просто более есстественны, это всё же данные, например, у реального документа нет поведение.
+ это путь наименшего сопротивления, когда отсувствует четких правил по архитектуры.

у реального документа нет поведение.

… а у кого "реального" есть поведение?

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

Ой ли?


"получив заказ от покупателя, оператор проверяет наличие всех позиций на складе, а затем отправляет покупателю счет на оплату"


Это разве не поведение?

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


  1. Мы их не проектируем (нам совершенно не важно, что оператор — живой организм, мы его устраняем из процесса, а покупатель — это внешний агент)
  2. Не важно, проектируем мы их или нет, подавляющее большинство систем, обслуживающих бизнес, работает именно с такого рода сценариями, следовательно, утверждение "в большинстве случаев не проектируем ничего с поведением" неверно.
например, у реального документа нет поведение.

Смотря где вы проведёте границу ваших абстракций. Можете рассматривать документ как бумажку. А можете рассматривать документ как бумажку и связанные с ней правила валидации данных. А можете рассматривать как бумажку, правила валидации и соответствующий бизнес-процесс. Не существует никакой самоцели делать модель данных в точности соответствующей тому, что пишется в бумажных аналогах. Делайте так, как удобнее.
Смотря где вы проведёте границу ваших абстракций.

Согласен.


А можете рассматривать как бумажку, правила валидации и соответствующий бизнес-процесс.

Но даже в этом случае вроде нет поведения, т.е. бумажка + правила о том что с ним делать.

А можете рассматривать как бумажку, правила валидации и соответствующий бизнес-процесс

Соответствующий бизнес-процесс обычно кроме документа включает и другие сущности. Почему его надо помещать в документ, а не в любую другую?


Не существует никакой самоцели

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

Соответствующий бизнес-процесс обычно кроме документа включает и другие сущности. Почему его надо помещать в документ, а не в любую другую?

Не «надо», а «можно». Проектируя архитектуру приложения, у вас стоит задача в том, чтобы она
а) эффективно решала поставленную задачу
б) была понятной
в) была сопровождаемой
г) укладывалась в бюджет разработки
Всё остальное вторично. Более того, даже всякие DRY, SOLID и иже с ними — это лишь методы достижения этих целей, которые в общем случае помогают их достичь, но бывают кейсы, когда их нужно нарушать.
Почему бизнес-процесс может быть помещён в документ? Например, в вашей системе документооборота центральной сущностью является документ, и не существует бизнес-процессов, не построенных вокруг какого-то документа. Они могут порождать другие документы, они связаны с сущностями участников и чего-либо ещё, но всегда вертятся вокруг одного документа. Здесь решение агрегировать их в документ будет вполне адекватным среди других решений.

Но факт остается фактом — документ сам себя не заполняет, его заполняет кто-то извне, и во всех процессах это так. Значит представление документа как анемичной модели точнее моделирует реальные процессы. Автоматизация убирает участие человека, но выполняемая им функция остается. Она может быть отнесена к объектам типа "Отдел" или вынесена в техническую сущность "сервис", но не к самому документу. У нее даже может быть свое состояние, которое не зависит от состояния документов.

Значит представление документа как анемичной модели точнее моделирует реальные процессы.

Да, но зачем точно моделировать реальные процессы? Задача автоматизации не состоит в том, чтобы их точно моделировать. В каких-то частных случаях это может быть нужно. В общем — нет. У вас есть задача, допустим, реализовать какой-то процесс согласования документа, и как оно внутри реализовано, для пользователей системы вообще чёрный ящик. Поэтому насколько ваша архитектурная модель повторяет их старые бумажки и телодвижения, они не оценят. Вам же для самого себя надо тоже писать модель не так, чтобы было больше похоже на бумажные процессы, а так, чтобы она
а) эффективно решала поставленную задачу
б) была понятной
в) была сопровождаемой
г) укладывалась в бюджет разработки

Ну так анемичная модель это все и дает. А точная модель дает то, что не надо искать, где она отличается от реальной бизнес-логики и как это менять при реальных изменениях.

Ну так анемичная модель это все и дает.

Да ничего она сама по себе не даёт, если честно. Всё в руках и голове разработчика. Испоганить анемичный объект с сервисом так же легко, как и старый добрый толстый объект.
Я не раз видел, как делают модель справочника, например, «категории клиентов», и к ней сервис, который позволяет CRUDить эти категории. И так — ко всем аналогичным справочникам. Просто потому, что в книжке где-то было сказано, что делать надо было так. В итоге получается приложение с кучей классов-прослоек, который кошмарен в плане сопровождения.

А в чем сложности с сопровождением?


Вы имеете в виду, лучше в один справочник все поместить? А как быть если потом у категорий клиентов появятся дополнительные атрибуты?

Вы имеете в виду, лучше в один справочник все поместить?

Нет, в данном случае такого сервиса вообще быть не должно. Только контроллер с формой редактирования/добавления. А операции вида «назначить категорию клиенту» относятся к сущности клиента и должны быть в сервисе управления клиентами.
А как быть если потом у категорий клиентов появятся дополнительные атрибуты?

Есть очень простое правило в разработке, которое, как ни странно, чаще соблюдают джуниоры и намного реже опытные разработчики: пишите код с заделом на будущее, если вы точно знаете, что ваше приложение будет масштабироваться, и как оно будет масштабироваться. И не пишите код с заделом на будущее, если вы не знаете, будет ли оно масштабироваться в будущем. Потому что это означает в 90% случаев, что оно масштабироваться не будет. Намного эффективнее переписать заново узкие места в 10% случаев, чем потратить ненужные усилия в 90%, закладывая в архитектуру то, что вам никогда не понадобится.
Только контроллер с формой редактирования/добавления.

Редактирования/добавления категорий клиентов? Ну так если не будет отдельного сервиса, код для CRUD будет в контроллере, контроллер и будет таким сервисом. Просто зачем писать его в контроллере, у него другая ответственность.


И не пишите код с заделом на будущее, если вы не знаете, будет ли оно масштабироваться в будущем.

Я все-таки не совсем понимаю, что вы имеете в виду. В контексте данного примера этот совет выглядит так, что вы предлагаете хранить категории клиентов и категории заказов в одной таблице, потому что у них одинаковые поля "id, name". Потому что если хранить в разных и иметь соответствующие классы в коде, то проблемы нет. Но я бы не назвал этот код "с заделом на будущее", так как у него есть преимущества сразу — ссылочная целостность в базе, типизация в коде.

Anemic не исключает сокрытия реализации = инкапсуляции

Как раз сокрытие реализации оно исключает. Скорее оно не исключает методы, даже по определению:

Anemic domain model is the use of a software domain model where the domain objects contain little or no business logic (validations, calculations, business rules etc.).


То есть такой подход вполне себе анемичен, открытые данные, с которыми можно работать извне и мало бизнес-логики:

class Box
{
    public int Height { get; set; }
    public int Width { get; set; }

    public int area()
    {
       return Height * Width;
    }
}

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

Пример: работа с денежными величинами. Не секрет, что во многих e-commerce системах денежные величины реализованы в виде чисел с плавающей запятой.

Не слишком правильный пример, т.к. в финансовых системах чаще используются специальные «денежные» типы без побочных эффектов точности. А в банковских так вообще вообще очень распространено использование целых чисел, представляя сумму операции изначально в копейках/центах
>Не секрет, что во многих e-commerce системах денежные величины реализованы в виде чисел с плавающей запятой

Не секрет для кого? Можно хотя бы пару примеров таких систем — их ведь много, правда же, это же не сложно показать парочку?
А в чем полезность заметки/статьи? В википедии написано тоже самое только подробней и точнее. А ещё есть чудесная книжка ООАД от Гради Буч- там не только определение, но и описание зачем оно нужно.

Но да инкапсуляциям как и почти все что связанно с хорошим тоном написания кода появилось давно — в годах этак 60, и соглашусь что это не каждый знает. Но! Скажем так — все придумали пол столетия назад, но пользоваться начали недавно, да и многие умные мысли из того времени не используются.
Да и какая разница когда оно появилось — важнее когда оно дошло до сообщества.
Лично мне пример с «не совсем целыми» деньгами показался полезным в психологическом смысле. Т.е. при написание полезно задаваться вопросом — а не размазываю ли я инфу по телу программы делая то или иное действие.
И что, тот факт, что хранение денег с плавающей точкой является хорошо известной формой bad practice, вас при этом не смущает?
«хорошо известной формой» ))) Смотря кому. Научные сотрудники — те еще программисты. На эту тему на Хабре как-то были даже чьи-то ироничные комменты. Мне ни разу не приходилось писать программу где бы фигурировали всякие «франки, фунты- стерлинги, да тугрики», но возможно/наверняка у меня были другие гм… " bad practice". Увы.
Ну, лично меня этому учили на первом курсе института. Это было… в 1975 году еще, при изучении Алгола. Как бы уже тогда было хорошо известно, что плавающая точка — она не для точных вычислений, а деньги лучше считать точно :)

Может и не хорошо, но что давно известной — это факт.
В будущем про это увы… забудут… или как раз таки нет? )
«Предположим, у тебя на счету в банке 8000 долларов, которые приносят тебе 8 процентов годовых. Раз в неделю банк пересчитывает твой счет. То есть в конце первой недели банк умножит сумму счета на 0,0015384 и прибавит результат к сумме счета. Твое состояние увеличится на 12,30 доллара. Правильно? Проверь на калькуляторе.Я подсчитал – результат был верен.
– Ровно двенадцать долларов и тридцать сантимов, – подтвердил я.
– А вот и нет, – решительно возразил он. – Прибыль-то составила 12,3072, не так ли?
– Да, но как прибавишь к счету семьдесят две сотые сантима?
– Да, это непросто, потому что банковские счета знают только вторую цифру после запятой.

Гарри Гаррисон „Рождение Стальной Крысы“.
))))))))))

… а при чем тут плавающая точка?

А… да. Согласен. Это несколько из другой оперы.
Редко кто осознанно размазывает знания о функционале по коду, думаю чаще это происходит из-за неверно выбранной абстракции, в таком случае поздно инкапсулировать — надо рефакторить код.

А деньги нормальные люди хранят целыми числами в копейках или в Decimal-типах, так что мимо.
Редко кто осознанно размазывает знания о функционале по коду, думаю чаще это происходит из-за неверно выбранной абстракции, в таком случае поздно инкапсулировать — надо рефакторить код.

Ну почему же поздно? Рефакторинг в данной ситуации и будет состоять в извлечении метода/класса, то есть, в «моей терминологии», в инкапсуляции кусочков кода куда-то там.

А деньги нормальные люди хранят целыми числами в копейках или в Decimal-типах, так что мимо.

А ненормальные обрабатывают во float-ах, и тоже неплохо зарабатывают.
Позволю себе не согласиться.

Главное назначение инкапсуляции — это сокрытие сложности, а вовсе не компоновка схожего функционала. Компоновка(как противоположность размазыванию) — это полезный, но побочный эффект инкапсуляции.
Более того, ни компоновка схожего функционала в одном месте, ни разнесение функционала над каким-то типом в различные части программы(неправильное использование которого как раз приводит к размазыванию и создаёт проблемы) не противоречат инкапсуляции и не обязательно её подразумевают. Это уже проблемы God Object, Single Responsibility и т.д.
Мне показалось, что мы говорим об одном и том же. Я тоже о сокрытии сложности, которая реализуется через убирание под кат лишних подробностей.
Подлинное назначение инкапсуляции — собрать в одном месте знания, относящиеся к устройству некой сущности, правилам обращения и операциям с ней.


Собрать в одном месте != спрятать.

Далее вы говорите и о том, что бы спрятать:

Инкапсуляция в данном случае — собрать (спрятать) в одном месте знание о том...


но подлинным назначением инкапсуляции это не называете.
Всё-таки в данном контексте собрать и спрятать — одно и то же. В проекте как правило весь код всем программистам физически доступен, никто доступ к нему не ограничивает. И всё же собрать в одном месте означает спрятать собранное из мест, где оно было/могло быть раньше, в специально отведённое место (класс, модуль, библиотеку — по желанию).

Например (условно), раньше в коде я после каждой операции сложения денег выполнял округление, чтобы избежать побочных эффектов точности:
sum = round(money_a + money_b)

И таких мест по коду было очень много. В каждой такой точке содержался кусочек знания о том, что реализация денег в этом коде хреновая (в виде float), деньги нужно постоянно округлять.

Потом я заменяю сложение с округлением на специальный вызов, который сам умеет правильно складывать деньги с нужным округлением:
sum = add_money(money_a, money_b)

Теперь вы читаете add_money, и не видите никаких round. Я спрятал round? — спрятал.
Таким вот нехитрым способом я прячу от глаз подальше подробности того, как нужно работать с деньгами в этом коде: просто вызывай add_money — и всё всегда будет хорошо, и никаких проблем с точностью.

А что я сделал? Я инкапсулировал код, который выполняет нужные операции, в отдельный модуль, в отдельную функцию. Инкапсулировал? — да. Спрятал? — тоже да.
Собрать в одном месте:

class A {
 public round(...);
 public add_money(...)
}


Инкапсуляция:
class B {
 private round(...);
 public add_money(...)
}
Инкапсуляция:

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

Потому что общеупотребимое в русском языке значение слова «инкапсуляция» является сокрытием по определению.
Главное назначение инкапсуляции — это сокрытие сложности, а вовсе не компоновка схожего функционала.
Я вот тоже хотел бы видеть инкапсуляцию именно в таком значении, но больше похоже, что вы заходите в сторону термина «абстракция».
Так ведь инкапсуляция — это один из шагов процесса абстрагирования)
А про что статья вообще? Не уверен, что это даже можно назвать статьей: введение, пара тезисов и пример, далекий от реальности (по крайней мере для меня).

Посмотрел предущую статью про мускулы. Похоже на тенденцию, людям нравится… Мини-блог? Бессвязные мысли вслух?

Может написать статью «Солнце светит» или «Ветер дует»? Или может обобщить «Ветер дует не так, как солнце светит»? /confused

Зато сколько комментариев! Поразительно просто.
Sign up to leave a comment.

Articles