Вы, похоже, используете довольно узкое определение «Инкапсуляция». Буду ли я прав, предполагая, что вы определяете инкапсуляцию как «Объединение данных с методами?»
Если я ошибаюсь, игнорируйте оставшуюся часть этого поста.
Инкапсуляция не является свободным термином; фактически, это определено Международной организацией по стандартизации. Эталонная модель ISO открытой распределенной обработки - определяет следующие пять концепций:
Сущность: любая конкретная или абстрактная вещь, представляющая интерес.
Объект: модель объекта. Объект характеризуется своим поведением и, вдвойне, своим состоянием.
Поведение (объекта): набор действий с набором ограничений относительно того, когда они могут происходить.
Интерфейс: абстракция поведения объекта, которая состоит из подмножества взаимодействий этого объекта вместе с набором ограничений на то, когда они могут произойти.
Инкапсуляция: свойство, заключающееся в том, что информация, содержащаяся в объекте, доступна только через взаимодействия на интерфейсах, поддерживаемых объектом.
Кроме того, мы можем сделать самоочевидное предложение: поскольку некоторая информация доступна через эти интерфейсы, некоторая информация должна быть скрыта и недоступна внутри объекта. Свойство, которое демонстрирует такая информация, называется скрытием информации, которое Парнас определил, утверждая, что модули должны быть спроектированы так, чтобы скрывать как сложные решения, так и решения, которые могут измениться, см. Одну из замечательных компьютерных статей:
http://www.cs.umd.edu/class/spring2003/cmsc838p/Design/criteria.pdf
Важно отметить, что не только данные скрыты в информации: это некоторая подгруппа поведения, связанная с объектом, которую трудно или вероятно изменить.
В своем посте вы, кажется, говорите, что разница между инкапсуляцией в ОО и в функциональном программировании связана с управлением данными, но, по крайней мере, согласно ISO и Parnas, управление данными не является ключом к инкапсуляции. Поэтому я не понимаю, почему инкапсуляция в функциональном программировании должна отличаться от инкапсуляции в ОО.
Кроме того, в своем посте вы упоминаете, что функциональное программирование обеспечивает инкапсуляцию «… методами, а не структурами данных». Я думаю, что это разница масштаба, а не абсолюта. Если я использую слово «Объект», а не «Структура данных» (опять же, пожалуйста, дайте мне знать, если я неправильно истолковываю), тогда вы, кажется, найдете значение в инкапсуляции ОО с помощью метода объектного и функционального программирования.
Тем не менее, согласно приведенному выше определению ISO, объект - это все, что я хочу моделировать. Таким образом, классы могут быть инкапсулированы в пакет, при условии, что некоторые из этих классов вносят вклад в интерфейс пакета (т. Е. Открытые классы пакета), а некоторые скрыты для информации (частные классы в пакете).
Точно так же методы инкапсулированы в классе - некоторые методы являются открытыми, а некоторые - закрытыми. Вы даже можете взять это на ступеньку ниже и сказать, что последовательные последовательности кода Маккабиана инкапсулированы в методы. Каждый формирует граф узлов, инкапсулированных в инкапсулированных областях; и все эти графы образуют стек графов. Таким образом, функциональное программирование может быть хорошо инкапсулировано на уровне функции / файла, но это ничем не отличается от метода / графа классов ОО и, по сути, также не отличается от графа класса / пакета ОО.
Также обратите внимание, что слово Парнас используется выше: изменить. Сокрытие информации касается потенциальных событий, таких как изменение сложных проектных решений в будущем. Вы спрашиваете, в чем сила ОО? Что ж, инкапсуляция, безусловно, является сильной стороной ОО, но тогда возникает вопрос: «В чем заключается сила инкапсуляции?», и ответ на этот вопрос один из потрясающей ясности: управление изменениями. В частности, инкапсуляция уменьшает максимальное потенциальное бремя изменений.
Понятие «Потенциальная связь» полезноЯ здесь.
«Соединение» само по себе определяется как «мера силы ассоциации, установленной соединением от одного модуля к другому» в другой из выдающихся работ вычислительной техники:
http://www.research.ibm.com/journal/sj/382/stevens.pdf
И, как говорится в документе, словами, которые с тех пор никогда не улучшались, «Минимизация соединений между модулями также сводит к минимуму пути, по которым изменения и ошибки распространяются в другие части системы, таким образом устраняя катастрофические эффекты« пульсации », когда изменения в одна часть вызывает ошибки в другой, что требует дополнительных изменений в другом месте, порождает новые ошибки и т. д. »
Однако, как здесь определено, есть два ограничения, которые можно легко снять. Во-первых, связывание не измеряет внутримодульные соединения, и эти внутримодульные соединения могут вызывать столько же эффектов «пульсации», сколько и межмодульных соединений (в документе определено «единство» для связи внутримодульных соединений). элементы, но это не определяется с точки зрения связей между элементами (т. е. ссылки на метки или адреса), с которыми была определена связь). Во-вторых, соединение любой компьютерной программы является заданным, в котором модули связаны или; в определении связи мало возможностей для управления потенциальными изменениями, о которых говорит Парнас.
Обе эти проблемы в некоторой степени решены с помощью концепции потенциальной связи: максимально возможного числа соединений, формируемых между всеми элементами программы. Например, в Java класс, который является частным для пакета (метод доступа по умолчанию) в пакете, не может иметь соединения, сформированные на нем (то есть никакие внешние классы не могут зависеть от него, несмотря на отражение), но открытый класс в пакете может есть зависимости от этого. Этот открытый класс будет способствовать потенциальной связи, даже если другие классы не зависят от него в данный момент - классы могут зависеть от него в будущем, когда дизайн изменится.
Чтобы увидеть силу инкапсуляции, рассмотрим принцип бремени. Принцип Бремени принимает две формы.
Сильная форма утверждает, что бремя преобразования набора сущностей является функцией количества преобразованных сущностей. Слабая форма утверждает, что максимальное потенциальное бремя преобразования набора сущностей является функцией максимального потенциального числа преобразованных сущностей.
Бремя создания или изменения любой программной системы является функцией количества созданных или измененных классов (здесь мы используем «Классы», предполагающие систему ОО, и занимаемся инкапсуляцией на уровне класса / пакета; мы мог бы в равной степени заботиться о функциональном / файловом уровне функционального программирования). (Обратите внимание, что «Бремя» - это современная разработка программного обеспечения, как правило, стоимость, или время, или оба.)
Классы, которые зависят от конкретного модифицированного класса, имеют более высокую вероятность воздействия, чем классы, которые не зависят от модифицированного класса.
Максимальное потенциальное бремя, которое может создать модифицированный класс, - это воздействие на все классы, которые зависят от него.
Следовательно, уменьшение зависимостей от модифицированного класса снижает вероятность того, что его обновление повлияет на другие классы, и, таким образом, уменьшает максимальную потенциальную нагрузку, которую может наложить этот класс. (Это немного больше, чем переосмысление статьи «Структурированный дизайн».)
Уменьшение максимального потенциального числа зависимостей между всеми классами в системе, следовательно, снижает вероятность того, что воздействие на определенный класс вызовет обновления для других классов, и, таким образом, уменьшает максимальную потенциальную нагрузку всех обновлений.
Инкапсуляция за счет уменьшения максимального потенциального числа зависимостей между всеми классами, следовательно, смягчает слабую форму Принципа нагрузки. Все это покрывается «Теорией инкапсуляции», которая пытается математически доказать такие утверждения, используя потенциальную связь в качестве логического средства структурирования программы.
Заметьте, однако, что когда вы спрашиваете:капсулирование - ключ ко всему стоящему коду? »Ответ наверняка будет: нет. Нет единого ключа ко всему стоящему коду. В некоторых случаях инкапсуляция - это всего лишь инструмент, помогающий улучшить качество кода и сделать его «стоящим».
Вы также пишете, что «… инкапсуляция может быть препятствием для гибкого расширения объекта». Да, это, безусловно, может: она действительно предназначена для того, чтобы препятствовать расширению проектных решений объекта, которые являются трудными или вероятными изменить. Это, однако, не считается плохой вещью. Альтернативный подход состоял бы в том, чтобы все классы были общедоступными и чтобы программа выражала свою максимальную потенциальную связь; но тогда слабая форма Принципа Бремени утверждает, что обновления будут становиться все более дорогостоящими; это затраты, против которых должны измеряться барьеры для расширения.
Наконец, вы проводите интересное сравнение между инкапсуляцией и семантикой, и, по вашему мнению, семантика ОО является ее большей силой. Я тоже не семантик (я даже не знал, что такое слово существовало до того, как добрый мистер Рэмси упомянул об этом в своем комментарии), но я предполагаю, что вы имеете в виду «семантика» в смысле «значение или интерпретация значения слова », и, по сути, класс с методом woof () должен называться Dog.
В этой семантике действительно есть большая сила.
Что мне любопытно, так это то, что вы противопоставляете семантику инкапсуляции и ищете победителя; Я сомневаюсь, что вы найдете один.
По моему мнению, есть две силы, которые мотивируют инкапсуляцию: семантическая и логическая.
Семантическая инкапсуляция просто означает инкапсуляцию, основанную на значении инкапсулированных узлов (если использовать общий термин). Поэтому, если я скажу вам, что у меня есть два пакета, один называется «животное», а другой - «минерал», а затем предоставлю вам три класса Dog, Cat и Goat и спросите, в какие пакеты эти классы следует инкапсулировать, тогда никакой другой информации, вы были бы совершенно правы, утверждая, что семантика системы предполагает инкапсуляцию трех классов в пакете «животное», а не в «минерал».
Другой мотивацией для инкапсуляции, однако, является логика и, в частности, исследование потенциальной связи, упомянутое выше. Теория инкапсуляции фактически обеспечивает уравнения для числа пакетов, которые должны использоваться для инкапсуляции ряда классов, чтобы минимизировать потенциальную связь.
Для меня инкапсуляция в целом - это компромисс между этим семантическим и логическим подходом: я позволю потенциальному соединению моих программ подняться выше минимума, если это сделает семантически легче понять программу; но огромные и расточительные уровни потенциальной связи будут предупреждением о том, что мою программу необходимо реструктурировать независимо от того, насколько она семантически очевидна.
(И если хороший мистер Рэмси все еще читает, не могли бы вы или ваши друзья-семантисты дать мне лучшее слово для фазы «семантики», которую я здесь использую? Было бы хорошо использовать более подходящий термин. )
С уважением,
Ed.