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