Подтвердить что ты не робот

Является ли прочность дизайна OO в семантике или инкапсуляции?

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

Итак, где же сила ООД? В принципе, функциональное программирование связывает богатство с глаголами, а не с существительными, и поэтому инкапсуляция и семантика предоставляются методами, а не структурами данных.

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

Или инкапсулирует ключ ко всему полезному коду?

Изменить: я имею в виду конкретно тип инкапсуляции OO. changeColor(door,blue) становится door.changeColor(blue).

4b9b3361

Ответ 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 позволяет потенциально связать мои программы с повышением выше минимального, если это делает программу семантически более понятной; но огромные и расточительные уровни потенциальной связи будут предупреждением о том, что моя программа должна быть реструктурирована независимо от того, насколько она семантически очевидна.

(И если хороший мистер Рэмси все еще читает, могли бы вы или ваши друзья-семантики дать мне лучшее слово для фазы "Семантика", которую я использую здесь? Было бы полезно использовать более подходящий термин.)

С уважением, Под ред.

Ответ 2

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

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

Ответ 3

Как программист Lisp, объектная система которого, возможно, не обеспечивает ни одного из них, я говорю: ни один из вышеперечисленных.

jwz: "объектная модель псевдо-Smalltalk теряет и что общие функции (соответственно ограниченные правилом без внешних внешних переопределений) выигрывают".

Я думаю, что желаемые атрибуты, которые вы и другие перечисляете здесь (инкапсуляция, модульность и т.д.), не так присущи OO, как вы думаете. Они часто предоставляются вместе с OO в стиле Java, но не являются чисто следствием этого.

Ответ 4

Изолирующая сложность - это IMO главная цель любого дизайна: инкапсуляция функциональности за интерфейс, который проще в использовании, чем сама функциональность.

OO предоставляет различные механизмы для этого - два упоминания о нем:

Инкапсуляция позволяет создавать пользовательскую поверхность, которая не зависит от фактической реализации. (перефразируя, "Упрощение означает другое" ).

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


Любой проект, достигающий определенного размера, становится упражнением в управлении сложностью. Я бы заявлял, что за эти годы программирование скользнуло по той сложности, которую мы научились управлять.

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

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

OO, OTOH - подход редукционистов: мы меняем POV, перейдя на более высокий уровень. В "старом OO" существует одна иерархия POV, интерфейсы - в этой модели - способ моделирования разных POV.

Если я могу так сказать, сила OO лучше подходит для "нормальных людей".

Ответ 5

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

Как выбрать наиболее эффективное "разделение" / "разбиение" большого проекта на достижение вышеуказанных целей? Опыт показал, что ОО является большим победителем здесь, и я думаю, что многие люди согласятся с тем, что два ключевых атрибута ОО, которые делают это хорошо:

  • Инкапсулированный: каждый класс инкапсулирует "секрет" - набор предположений, специфичных для конкретной реализации, которые, вероятно, будут иметь место для изменения по времени его реализации - и предоставляет интерфейс, который не соответствует этим предположениям; наложение таких инкапсулированных абстракций позволяет архитектовать надежную конструкцию, где компоненты/реализации могут легко быть заменены перед ожидаемыми изменениями.
  • Noun-centric: в большинстве доменов люди кажутся лучше сначала разлагать модель домена, думая о существительных/данных домена, а затем идентифицируют поддерживающие глаголы, которые связаны с каждым существительным.

Что касается функционального программирования (FP) по сравнению с OO, я blogged об этом, но вкратце я думаю, что FP больше относится к методам внедрения, тогда как OO больше относится к структуре и дизайну программы, и, таким образом, эти два являются взаимодополняющими, причем OO является более доминирующим на "большом" конце шкалы, а FP более доминирует на "малом" конце. То есть, по большому проекту, структура высокого уровня лучше всего описывается дизайном класса OO, но многие детали модуля (реализации и детали форм интерфейсов модулей) лучше всего формируются FP влияния.

Ответ 6

Объектно-ориентированная проектная прочность пропорциональна длительности связывания в дизайне. Это понятие Кей, относящееся к OO, а не понятие Nygaard. Алан Кей написал:

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

Большая часть литературы игнорирует позднюю привязку в пользу идеи объектной ориентации С++.

Ответ 7

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

Механика ООП легко реализуется в простых C с помощью структур и указателей функций. Вы даже можете немного почувствовать ООП таким образом. Тем не менее, идиомы ООП не так уж и ожидаются в такой среде. Когда существует реальная поддержка языка для ООП, тогда проявляется выразительность парадигмы, и способ, которым язык реализует идею, оказывает очень реальное влияние на то, что "сказано" и как. Например, см. Различия в коде с использованием закрытий /lambdas в lisp, python, ruby ​​и т.д.

Итак, в конце концов, речь идет не о компонентах и ​​базовых концепциях, а о том, как они объединяются и используются, что делает OO на С++ тем, чем он является.

Ответ 8

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

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

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

Ответ 9

IMHO, OO просто означает объекты, взаимодействующие с другими объектами. Инкапсуляция просто означает абстрагирование понятия. Итак, вы создаете Socket и .Connect() для чего-то. Как он соединяется, вам все равно (это в основном мое определение инкапсуляции).

И, чистое функциональное программирование может использовать объект для связи.. но эти объекты должны быть неизменными. Итак, снова ИМХО, FP может легко использовать концепцию ОО; Императивный язык, такой как C, все еще может использовать концепцию OO.. например, файл для каждого "класса" с частным сектором, который не должен использоваться.

Ответ 10

Ваш вопрос гласит, что вы хотите извлечь выгоду из дом, анализируя кирпич.

Наличие возможности предоставления семантического контекста и инкапсуляции являются лишь основными возможностями класса в OO. (Как кирпич может выдержать определенную силу и потребовать определенное пространство.)

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

Там много шаблонов дизайна, которые могут использоваться для OO программирование. Большинство из них полагаются на способности "инкапсуляции" и "семантический", о котором вы говорили.

Некоторые из этих шаблонов являются даже ответом на третий абзац вашего вопроса:

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

Ответ 11

Реальная мощность OO заключается в полиморфизме, а не в инкапсуляции. Инкапсуляция в определенной степени достижима и используется в функциональных языках, но полиморфизм будет очень неудобным, если он будет реализован на функциональном языке.

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

@Phil. Разница, о которой вы говорили, если я правильно вас понимаю, находится между тем, как программа вызывает данные/метод: в оо сначала возникает объект/экземпляр, а затем вызывается метод данных/метода объекта через объект; в функциональном методе напрямую вызывается.

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