ООП сложно, потому что это не естественно?


86

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

Обратите внимание, что в повседневной жизни отношения и действия существуют главным образом между объектами, которые были бы экземплярами не связанных классов в ООП. Примеры таких отношений: «мой экран находится на вершине таблицы»; «Я (человек) сижу на стуле»; "машина на дороге"; «Я печатаю на клавиатуре»; «кофемашина кипит вода», «текст отображается в окне терминала».

Мы думаем в терминах двухвалентных (иногда трехвалентных, как, например, в «Я подарил вам цветы») глаголов, где глагол - это действие (отношение), которое воздействует на два объекта для получения некоторого результата / действия. Основное внимание уделяется действию, и два (или три) [грамматических] объекта имеют одинаковое значение.

Сравните это с ООП, где вы сначала должны найти один объект (существительное) и сказать ему выполнить какое-то действие с другим объектом. Способ мышления смещен с действий / глаголов, действующих на существительные, на существительные, действующие на существительные, - это как если бы все говорилось пассивным или рефлексивным голосом, например, «текст показывается окном терминала». Или, может быть, «текст рисуется в окне терминала».

Мало того, что акцент смещен на существительные, но одному из существительных (назовем это грамматическим предметом) дается более высокая «важность», чем другому (грамматическому объекту). Таким образом, нужно решить, скажете ли вы терминалWindow.show (someText) или someText.show (терминалWindow). Но зачем обременять людей такими тривиальными решениями без каких-либо эксплуатационных последствий, когда действительно нужно показать (TerminalWindow, someText)? [Последствия являются незначительными с точки зрения эксплуатации - в обоих случаях текст отображается в окне терминала - но могут быть очень серьезными при проектировании иерархий классов, а «неправильный» выбор может привести к запутанному и трудному в обслуживании коду.]

Поэтому я бы сказал, что основной способ выполнения ООП (на основе классов, одна отправка) сложен, потому что он НАТУРАЛЬНЫЙ и не соответствует тому, как люди думают о мире. Общие методы из CLOS ближе к моему мышлению, но, увы, это не распространенный подход.

Учитывая эти проблемы, как / почему случилось так, что в настоящее время основной способ сделать ООП стал настолько популярным? И что, если что, можно сделать, чтобы свергнуть это?


ООП предназначен для «программирования», он создан для того, чтобы компиляторы могли наслаждаться им. это не способ моделировать реальный мир каким-либо образом. Во время обучения ООП часто используются примеры из реального мира, такие как класс животных и класс прямоугольников, но это всего лишь примеры для упрощения концепций. К сожалению, язык программирования и парадигмы «происходят» неэволюционно и ненаучно. За немногими исключениями, процесс языкового проектирования, как правило, дитя, о котором мало кто догадывается!
NoChance

3
Я бы не согласился с утверждением, что «ООП фокусируется на разработке отдельных классов и их иерархий». с тех пор, как Maybie находится в фокусе определенных реализаций ООП, я, например, обнаружил, что языки динамического ООП обычно не имеют больших иерархий или даже классов. Что ж, определение ООП может измениться в будущем, есть попытка изменить даже Объект один wcook.blogspot.com/2012/07/proposal-for-simplified-modern.html
Azder

1
ООП идентифицирует объекты в системе и строит классы на основе этих объектов. А не наоборот. Вот почему я также не согласен с тем, что «основное внимание ООП уделяется разработке отдельных классов и их иерархий».
Раду Мурзеа


1
Я думаю, что это очень субъективный вопрос, и он полон странных предположений об ООП и о том, что такое «реальный мир» и как люди думают о проблемах. И, наконец, он даже спрашивает: «А что, если вообще, можно сделать, чтобы свергнуть его с престола?» что действительно показывает, что у ОП очень твердое мнение по этому поводу. Если вы настолько «религиозны» в отношении парадигм программирования, я думаю, вам не нужны никакие ответы ... вы уже знаете, что хотите услышать. Если бы я знал об этом вопросе, когда его впервые спросили, я бы, вероятно, проголосовал за его закрытие ...
Саймон Леманн,

Ответы:


97

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

  1. Некоторые люди ведут себя так, как будто это единственно верный способ программирования, а все остальные парадигмы ошибочны. ИМХО, каждый должен использовать многопарадигмальный язык и выбрать лучшую парадигму для подзадачи, над которой он сейчас работает. Некоторые части вашего кода будут иметь стиль OO. Некоторые будут функциональными. У некоторых будет прямой процедурный стиль. С опытом становится очевидным, какая парадигма лучше для чего:

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

    б. Процедурный метод лучше всего подходит для случаев, когда у вас есть набор поведений, которые не сильно связаны с какими-либо конкретными данными. Например, возможно они работают с примитивными типами данных. Здесь проще всего представить поведение и данные как отдельные объекты. Пример: числовой код.

    с. Функциональность лучше всего подходит, когда у вас есть что-то, что довольно легко написать декларативно, так что существование любого состояния вообще является деталью реализации, которую можно легко абстрагировать. Пример: Карта / Уменьшить параллелизм.

  2. ООП обычно показывает свою полезность в больших проектах, где действительно необходимо иметь хорошо инкапсулированные фрагменты кода. Это не случается слишком много в проектах новичка.


4
Я думаю, что важным вопросом в вопросе было не то, является ли ООП естественным, но является ли основной подход к ООП наиболее естественным. (Хороший ответ в любом случае.)
Джорджио

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

2
ООП действительно на другой оси, чем процедурный / функциональный; он решает, как организовать и инкапсулировать код, а не как описывать операции. (Вы всегда сотрудничаете с ООП с помощью парадигмы исполнения. Да, существуют ООП + функциональные языки.)
Донал Феллоуз

1
Нельзя ли сказать, что ООП - это просто коробки, в которые мы помещаем процедурные вещи?
Эрик Реппен

В ООП вы все еще можете писать методы. Что делает ООП слабее процедурного программирования?
Мерт Акчакая

48

ИМХО это вопрос личного вкуса и способов мышления. У меня нет особых проблем с ОО.

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

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

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

Если между объектами есть отношения, то они связаны по определению. В ОО вы можете выразить это с помощью зависимости ассоциации / агрегации / использования между двумя классами.

Мы думаем в терминах двухвалентных (иногда трехвалентных, как, например, в «Я подарил вам цветы») глаголов, где глагол - это действие (отношение), которое воздействует на два объекта для получения некоторого результата / действия. Основное внимание уделяется действию, и два (или три) [грамматических] объекта имеют одинаковое значение.

Но у них все еще есть свои четко определенные роли в контексте: субъект, объект, действие и т. Д. «Я подарил тебе цветы» или «Ты подарил мне цветы» - это не одно и то же (не говоря уже о том, «Цветок дал мне тебя»): -)

Сравните это с ООП, где вы сначала должны найти один объект (существительное) и сказать ему выполнить какое-то действие с другим объектом. Способ мышления смещен с действий / глаголов, действующих на существительные, на существительные, действующие на существительные, - это как если бы все говорилось пассивным или рефлексивным голосом, например, «текст показывается окном терминала». Или, может быть, «текст рисуется в окне терминала».

Я не согласен с этим. ИМХО английское предложение «Билл, иди к черту» читается более естественно в программном коде, bill.moveTo(hell)а не move(bill, hell). И первый фактически более похож на оригинальный активный голос.

Таким образом, нужно решить, скажете ли вы терминалWindow.show (someText) или someText.show (терминалWindow)

Опять же, это не то же самое, что попросить терминал показать некоторый текст или попросить текст показать терминал. ИМХО, вполне очевидно, какой из них более естественный.

Учитывая эти проблемы, как / почему случилось так, что в настоящее время основной способ сделать ООП стал настолько популярным?

Может быть, потому что большинство разработчиков OO видят OO иначе, чем вы?


15
+1 за прямое упоминание о том, что сообщения между объектами и их важность от Алана Кея
bunglestink

3
@zvrba, действительно, были и другие пионеры ОО, но это не относится к этой дискуссии. «Самое естественное - попросить показать текст». - теперь вы используете тот же пассивный голос, который, по вашему мнению, настолько «неестественен» в ООП.
Петер Тёрёк

5
@zvrba, вы говорите: «всегда есть« агент »[...], который делает что-то», но протестует против ОО подхода, заключающегося в идентификации и присвоении имен этим агентам (объектам), и обращаются с ними как с первоклассными гражданами на языке , Для меня это является частью моделирования проблемной области - вам все равно нужно выполнить эту работу, просто затем сопоставить полученную модель домена с кодом другим способом, в зависимости от того, является ли ваш язык ОО или нет.
Петер Тёрёк

6
@zvrba, это не ОО как таковое, а разработчик / дизайнер, который принимает решение о ролях и обязанностях различных объектов. Использование подхода OO может привести к хорошим или плохим моделям и проектам предметной области, так же как использование ножа может дать вам кусочек хорошего хлеба или кровоточащий палец - все же мы не виним нож, потому что это всего лишь инструмент. Также обратите внимание, что понятия / объекты / агенты в модели являются абстракциями вещей в реальном мире, и как таковые всегда ограничены и искажены, фокусируясь только на определенных «интересных» аспектах.
Петер Тёрёк

6
@zvrba, автомобиль действительно не заводится по собственной воле - точно так же, как Carобъект, start()только когда кто-то явно вызывает его метод.
Петер Тёрёк

10

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

... но в центре внимания ООП находится разработка отдельных классов и их иерархий.

ООД НЕ об этом. OOD - это выяснение того, как вещи ведут себя и взаимодействуют.

Мы думаем в терминах двухвалентных (иногда трехвалентных, как, например, в «Я подарил вам цветы») глаголов, где глагол - это действие (отношение), которое воздействует на два объекта для получения некоторого результата / действия. Основное внимание уделяется действию, и два (или три) [грамматических] объекта имеют одинаковое значение.

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

Я не вижу делателя более важным, чем то, что с ним что-то делает.

Но зачем обременять людей такими тривиальными решениями без каких-либо эксплуатационных последствий, когда действительно нужно показать (TerminalWindow, someText)?

Для меня это то же самое с другой нотацией. Вы все еще должны решить, кто шоу-шоу, а кто шоу-е. Как только вы это знаете, в ООД решения не принимается. Windows показать текст -> Window.Show (текст).

Многие вещи там (особенно в унаследованной области) говорят, что это ОО, когда это не так. Например, существует огромное количество кода на C ++, который не реализует ни черта OOD.

OOD легко, когда вы выходите из себя, решая проблему для компьютеров. Вы решаете проблемы для вещей, которые делают вещи.


10
Я не люблю ООД именно потому, что предпочитаю думать о том, как решить проблему, точка. Я не хочу думать о том, как перевести естественный язык проблемной области в чужой мир объектов, сообщений, наследования и так далее. Я не хочу изобретать иерархические таксономии, где они не существуют естественным образом. Я хочу описать проблему на естественном языке и решить ее как можно проще. И, кстати, мир состоит не только из «вещей, которые делают вещи». Ваш взгляд на реальность чрезвычайно узок.
SK-logic

7
@ Matt Ellen, я пишу программы, которые моделируют поведение объектов, которые не являются «вещами» и не «делают» никаких «вещей». Любая неизменная сущность ничего не делает. Любая математически чистая функция ничего не делает - это просто отображение из одного набора в другой, и этот мир в основном описывается такими функциями. Любой логический формализм ничего не «делает». Да, OOD мне не поможет, потому что я могу использовать гораздо более мощные абстракции и модели. Возвращение к примитивному, ограниченному, ограничивающему OOD сильно затруднит мне жизнь.
SK-logic

2
@Matt Ellen, да, я хотел бы видеть ссылки, подтверждающие такие странные утверждения, что мир лучше рассматривать как набор «вещей, которые делают вещи», или «объектов, которые взаимодействуют через сообщения». Это совершенно неестественно. Возьмите любую научную теорию (поскольку все они настолько близки к моделированию реального мира, насколько это возможно на данном этапе), и попытайтесь переписать ее, используя вашу терминологию. Результат будет неуклюжим и неловким.
SK-logic

4
@ Antonio2011a, нет единой парадигмы программирования или моделирования, которая могла бы эффективно охватить все возможные проблемные области. ООП, функционал, поток данных, логика первого порядка и все остальное - все они являются проблемными предметно-ориентированными парадигмами и не более того. Я только защищаю разнообразие и непредвзятый подход к решению проблем. Сужать ваше мышление до одной парадигмы просто глупо. Наиболее близким к универсальному подходу, не ограничивающему вас единой семантической структурой, является en.wikipedia.org/wiki/Language-oriented_programming
SK-logic

3
@ Калмариус, почему ты сделал программирование проще для компьютеров? Это просто глупо. Это люди, которые должны делать более тяжелую работу.
Мэтт Эллен

7

Может быть, я не могу понять, но:

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

Для меня это довольно ясно: собака - это животное, животное должно есть, моя собака - это собака, поэтому она должна есть ...

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

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


1
Что именно вы делали, чтобы перейти от кобола к фортрану, а затем к сборке (и остальным)?
Ладья

1
Неправильный порядок. На самом деле я начал с Basic, затем перешел на Fortran, а затем в Assembly и Cobol (да, это правильный порядок: сначала Assembly). Первым компьютером в моей жизни был «гигантский» мэйнфрейм, 256 КБ памяти, пишущая машинка на его консоли, подпитывающая его перфокартами, потому что я был его оператором. Когда я поднялся достаточно, чтобы стать системным программистом, подозрительная вещь под названием PC-AT приземлилась на мой стол. Так что я погрузился в GW-Basic, Turbo-Pascal, ... и так далее.
Неревар

1
Я не обращался к этому. Больше к вашей области работы; потому что я не знаю многих людей (кто-нибудь на самом деле), которые имели дело с COBOL (ориентированным на бизнес), fortran (научный домен), ассемблером (более ориентированным на cs) и другими. Тем не менее, они профессиональные программисты или нет.
Грач

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

6

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

Затем я прочитал SICP и пришел к новому пониманию того, что на самом деле речь идет о типах данных и контроле доступа к ним. Все проблемы, с которыми я столкнулся, были основаны на ложной предпосылке, что в ООП вы моделируете мир.

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


Спасибо за указание на опасность попытаться смоделировать мир.
Шон Макмиллан

4

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


5
Что ж, это в равной степени верно для любого вида формальных обозначений, пытающихся точно описать реальный мир.
Петер Тёрёк

1
@ Петер Тёрёк, точно моя точка зрения. Там нет единого формализма, который охватывает все. Вы должны использовать их всех во всем их страшном множестве. И именно поэтому я верю в языково-ориентированное программирование - оно позволяет применять различные, часто несовместимые формализмы в единое целое кода.
SK-logic

1
Все можно разделить на иерархические таксономии. Хитрость заключается в том, чтобы придумать схемы, которые имеют смысл. Часто происходит множественное наследование. Большая разница между программным обеспечением и реальным миром заключается в том, что в реальном мире нам часто приходится делать выводы или открывать схемы категоризации; в программном обеспечении мы их изобретаем.
Калеб

1
Используя термин «иерархическая таксономия», я думаю, что вы думаете о наследовании. Наследование действительно трудно рассуждать. Вот почему люди предлагают использовать композицию вместо наследования.
Фрэнк Шиарар

1
@Frank: в реальном мире существует много типов иерархических таксономий, из которых наследование является только одним. Чтобы сделать все это правильно, требуются лучшие инструменты, чем ООП (например, онтологические рассуждения), и это создавало проблемы для философов на протяжении тысячелетий ...
Донал Феллоуз

4

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

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

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

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

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


3

Это только часть того, что не так с ООП.

По сути, функции становятся гражданами второго сорта, и это плохо.

Современные языки (ruby / python) не страдают от этой проблемы и предоставляют функции в качестве объектов первого класса, а также позволяют создавать программы без построения какой-либо иерархии классов.


ООП кажется мне очень естественным, на самом деле мне трудно думать о задачах программирования как-то иначе. Тем не менее, за эти годы я понял, что ООП имеет тенденцию переоценивать существительные над глаголами. Эта напыщенная речь 2006 года помогла мне понять это различие: steve-yegge.blogspot.com/2006/03/…
Джим в Техасе

3

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


3

РЕДАКТИРОВАНИЕ

Прежде всего, я хотел бы сказать, что я никогда не находил ООП сложным или сложным, чем другие парадигмы программирования. Программирование по своей сути сложно, потому что оно пытается решить проблемы из реального мира, а реальный мир чрезвычайно сложен. С другой стороны, когда я читал этот вопрос, я спрашивал себя: является ли ООП «более естественным», чем другие парадигмы? И поэтому эффективнее?

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

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

Я работал в основном с языками ООП (C ++, Java), но у меня часто возникает ощущение, что я могу быть столь же продуктивным, используя Pascal или Ada, хотя я никогда не пробовал их в больших проектах.

Сравните это с ООП, где вы сначала должны найти один объект (существительное) и сказать ему выполнить какое-то действие с другим объектом.

[порез]

Поэтому я бы сказал, что основной способ выполнения ООП (на основе классов, одна отправка) сложен, потому что он НАТУРАЛЬНЫЙ и не соответствует тому, как люди думают о мире. Общие методы из CLOS ближе к моему мышлению, но, увы, это не распространенный подход.

Когда я прочитал этот последний абзац более внимательно, я наконец понял суть вашего вопроса, и мне пришлось переписать свой ответ с нуля. :-)

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

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


3

Прекратите искать исключительно парадигму ООП и попробуйте немного JavaScript.

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

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

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

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

Итак, я думаю, что я говорю, это: это не проблема переключения типа заявления. Это смешивать и сочетать. Проблема в языках и причудах, которые хотят, чтобы вы поверили, что это одна вещь. Как может, например, младший Java-разработчик по-настоящему ценить ООП, если он думает, что он всегда делает это правильно по умолчанию?


2

Мне это объяснили с помощью тостера и машины. У обоих есть пружины, так что у вас был бы «пружинный» объект, и они были бы разных размеров, сил и тому подобное, но они оба были бы «пружинами», а затем распространяли эту метафору на автомобиль, если бы у вас было много колес (Колеса, очевидно, плюс руль, и т. Д.), И это имело большой смысл.

Затем вы можете думать о программе как о списке объектов, и гораздо проще визуализировать, чем «Это список вещей, которые делают вещи, поэтому он не похож на тот список инструкций, которые вы видели раньше»

Я думаю, что настоящая проблема с ООП состоит в том, как это объясняется людям. Часто (в моих университетских классах) я вижу, что это объясняется тем, что «речь идет о множестве классов, которые делают мелочи, и вы можете создавать объекты из этого», и все это сбивает с толку многих людей, потому что они используют то, что по сути абстрактно термины, объясняющие эти понятия, а не конкретные идеи, которые люди поняли, когда им было 5 лет, играя с лего.


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

2

Это естественный способ думать о мире через категоризацию. Это более или менее то, о чем ОО. ООП сложно, потому что программирование сложно.


Но вы классифицируете в соответствии с тем, имеют ли некоторые объекты общие атрибуты или общее поведение? Все ли имеет имя и фамилию человек? Это все, что гуляет с животным?
zvrba

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

1
@zvrba: Мой ответ на вопрос, поставленный в комментарии, таков it doesn't matter. Все, что имеет имя и фамилию, является человеком для каждой программы, которая заботится только о людях. Для любой программы, которая не знает людей или не людей, это IHasNameAndSurname. Объекты должны только решить проблему под рукой.
Том W

@Jeff O Даже в пределах одного и того же вида / породы / популяции существует вариация и нет идеального (существенного) примера. Итак, да, ОО не таков, как природа на самом деле, но он хорошо подходит к тому, как люди думают естественным путем.
Том Хотин - Tackline

2

Я думаю, что некоторые трудности возникают, когда люди пытаются использовать ООП для представления реальности. Всем известно, что у машины четыре колеса и двигатель. Все знают, что автомобили могут Start(), Move()и SoundHorn().

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


1

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

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

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


2
Вы когда-нибудь видели правильную систему модулей? Как вы можете сказать, что ООП - лучшая доступная вещь? Модули SML намного, намного мощнее. Но даже пакетов Ada достаточно для большинства случаев, даже без малейшего намека на ООП.
SK-logic

@ SK-logic, я думаю, ты зациклился на слишком точных определениях. Под ООП я не имею в виду классы , я имею в виду логическую группировку «глаголов» по ​​«существительным», с которыми они работают, и возможность повторного использования и специализации этих глаголов на основе конкретных существительных, с которыми они работают. Классы являются самой известной реализацией этого, но не единственной реализацией. Я признаю, что не знал о модулях SML, но первым примером, который я увидел, когда искал его, была реализация очереди, которая могла бы прийти из любой книги разработки ОО с изменениями синтаксиса, чтобы сделать ее функциональной.
Карл Билефельдт

просто было бы нечестно отдавать несчастному ООП слишком большой кредит за то, что ему не принадлежит. Модули - отличное изобретение. Первоклассные модули просто фантастические. Но ООП не имеет к ним никакого отношения. Некоторые языки ООП приняли некоторые из функций модуля (прежде всего - пространства имен), но модули являются гораздо более общей и мощной концепцией, чем классы. Вы сказали, что занятия "лучшие", что далеко от истины. Первоклассные модули намного лучше. И, конечно же, системы типов гораздо шире и глубже, чем просто ОО с его подтипами.
SK-logic

1
«Это как старая поговорка о капитализме: ООП - наихудшая система организации программного обеспечения, кроме всего остального, что мы пробовали»: возможно, мы не пытались достаточно долго. :-)
Джорджио

1
Я думаю, что вы имеете в виду «демократия»: quotationspage.com/quote/364.html
nicodemus13

1

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

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

Существует также парадигма «все - список или элемент», используемая в LISP. Мне нравится упоминать как отличную вещь от функционального программирования . PHP использует это в ассоциативных массивах.

Парадигмы ООП и «Все является списком или элементом» рассматриваются как два из БОЛЕЕ ЕСТЕСТВЕННЫХ стилей программирования, как я помню в некоторых классах искусственного интеллекта.

Звучит для меня странно: «ООП не является естественным», возможно, то, как вы учитесь, или то, как вас учили об ООП, неверно, но не само ООП.


1

Учитывая эти проблемы, как / почему случилось так, что в настоящее время основной способ сделать ООП стал настолько популярным? И что, если что, можно сделать, чтобы свергнуть это?

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

Чтобы свергнуть ОО, создайте язык, который позволяет постепенно переходить от того, что большинство программистов знают сегодня (в основном процедурное, с небольшим ОО), к предпочитаемой вами парадигме. Убедитесь, что он предоставляет удобные API для выполнения общих задач и хорошо его продвигает. Вскоре люди будут создавать программы для X-in-name-only на вашем языке. Тогда вы можете ожидать, что людям потребуются годы и годы, чтобы хорошо освоить X.


ОП не утверждает, что ОО в целом плоха и должна быть свергнута с должности, но что «в настоящее время основной способ выполнения ООП» не является наиболее естественным (по сравнению с «множественной отправкой»).
Джорджио

OP также кажется чрезмерно сосредоточенным на определении иерархии типов, где лучшие OO-программы имеют тенденцию больше полагаться на интерфейсы и композицию. Если для Multiple dispatch выбрано значение X, то создание языка, который позволит людям постепенно освоить навыки, связанные с многократной диспетчеризацией, все еще является ключом к изменению среды.
Шон Макмиллан

1

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

Если вы правильно понимаете, ООП - это черные ящики (объекты), на которых есть кнопки, которые можно нажимать (методы). Классы только для того, чтобы помочь организовать эти черные ящики.

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

Другое дело, что компьютер просто выполняет инструкции последовательно. Давайте предположим, что у вас есть объект VCRи Televisionобъект, как бы вы воспроизводили видео? Вы, вероятно, напишите что-то вроде этого:

connect(television, vcr);
vcr.turnOn();
television.turnOn();
insert(vcr, yourFavoriteCasette);
vcr.play();
while (vcr.isPlaying()) {} // Wait while the VCR is playing the casette.
vcr.eject();
vcr.turnOff();
television.turnOff();

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

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


0

Взгляните на DCI (данные, контекст и взаимодействие), изобретенные изобретателем шаблона MVC.

Цель DCI (цитируется из Википедии):

  • Дайте поведению системы первоклассный статус над объектами (существительными).
  • Чисто отделить код для быстро меняющегося поведения системы (что делает система) от кода для медленно меняющегося знания предметной области (что такое система) вместо того, чтобы объединять оба в одном интерфейсе класса.
  • Поддерживать объектный стиль мышления, близкий к ментальным моделям людей, а не классовый стиль мышления.

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


0

Часто можно услышать, что ООП естественно соответствует тому, как люди думают о мире. Но я бы категорически не согласился с этим утверждением (...)

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

(...) но в центре внимания ООП находится разработка отдельных классов и их иерархий.

Это утверждение входит в разумную территорию, учитывая, насколько распространены неправильные представления об ООП и насколько чувствительно ОО к определению. У меня есть более десяти лет в этой области, я работаю в отрасли и занимаюсь научными исследованиями в области прог. языки, и я могу вам сказать, что я потратил много лет, чтобы отучиться от «основного ОО», потому что я начал замечать, насколько он отличается (и уступает) от того, на что были нацелены более ранние создатели. Для современной, современной трактовки этого предмета я бы сослался на недавние усилия В. Кука:

«Предложение по упрощенным, современным определениям« объект »и« объектно-ориентированный » http://wcook.blogspot.com.br/2012/07/proposal-for-simplified-modern.html

Учитывая эти проблемы, как / почему случилось так, что в настоящее время основной способ сделать ООП стал настолько популярным?

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

И что, если что, можно сделать, чтобы свергнуть это?

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

Наконец, поделитесь своими результатами с нами.


-1

Возьмем Java: объекты являются своего рода узким местом абстракции, большинство «вещей» являются либо строго подкомпонентами объектов, либо используют объекты в качестве своих подкомпонентов. Объекты должны быть достаточно многоцелевыми, чтобы весь слой абстракции между этими двумя типами вещей - многоцелевой означает, что нет единой метафоры, которую они воплощают. В частности, Java делает объекты (и классы) единственным слоем, через который вы вызываете / отправляете код. Честно говоря, такое количество вещей, которые воплощают объекты, делает их слишком сложными. Любое их полезное описание должно быть ограничено какой-либо специализированной или ограниченной формой.

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

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

Напротив, объект, который представляет процесс, например «шифровать» или «сжимать» или «сортировать», выглядит как «глагол».

Некоторые объекты используются для их роли в качестве пространства имен, например, место для размещения «статической» функции в Java.

Я склонен согласиться с аргументом, что Java слишком тяжел для вызовов метода объекта, с диспетчеризацией для объекта. Вероятно, это потому, что я предпочитаю классы типов Haskell для управления диспетчеризацией. Это ограничение отправки и является функцией Java, но не для большинства языков или даже для большинства ОО-языков.


-3

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

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

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

Если вы сравните правильно написанный ОО-код с плохо написанным процедурным кодом, то вы всегда будете приходить к неправильному выводу. Очень немногие проекты требуют объектно-ориентированного дизайна. Если вы являетесь IBM и управляете огромным проектом, который многие годы должны поддерживать несколько разработчиков, выберите Object Oriented. Если вы пишете небольшой блог или торговый сайт для клиента, подумайте дважды.

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

Обязательным требованием для любого объектно-ориентированного программиста должно быть знание того, как написать шахматное приложение на ассемблере для максимально доступной памяти в 16 КБ. Затем они научились бы обрезать жир, избавляться от лени и находить гениальные решения.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.