В чем смысл ООП?

126

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

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

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

Так что мне здесь не хватает? В чем ценность ООП и почему все время и деньги не помогли улучшить программное обеспечение?

DrPizza
источник
11
Ваша аналогия - слишком высокая абстракция для предполагаемого «варианта использования»; стол, пень, капот, чьи-то колени - это композиции из молекул, атомов, протонов, нейтронов, электронов, образующие достаточно большую площадь поверхности, чтобы ваша задница могла упираться силой тяжести.
icelava
38
Независимо от того, сколько раз запускается один и тот же поток, он всегда вызывает большой интерес (несмотря на то, что дублирование здесь обычно не допускается). И, конечно же, выбранный ответ всегда совпадает с первоначальным мнением спрашивающего.
ТМ.
4
Проблема с ООП - неспособность поместить его в контекст. Он отлично подходит для некоторых целей, но не для всех. Это отличный инструмент. Это паршивое Евангелие.
Майк Данлэйви,
16
Мне очень жаль, но я не могу избавиться от ощущения, что вы никогда не программировали на каком-либо языке. Вот почему: ООП - это основа работы для базовых библиотек компонентов во всех современных средах (Java, .NET, Python, Ruby - это лишь некоторые из основных). Все эти базовые библиотеки используются повторно ежедневно, поэтому, если это не в счет, я не знаю, что именно. Так что не поймите меня неправильно, но повторное использование кода, если факт - и чрезвычайно распространенный! Я не хочу, чтобы это звучало оскорбительно - просто подчеркну здесь.
Маттиас Гринишак
2
@George Jempty: Это был Джоэл Спольски в «Как Microsoft проиграла войну API» ( joelonsoftware.com/articles/APIWar.html ), заголовок отрывка - «Автоматическая передача выигрывает день».
GodsBoss

Ответы:

24

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

Объектно-ориентированные представления не кажутся универсально более или менее пригодными для использования.

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

Это из статьи «Об удобстве использования объектно-ориентированных представлений» из сообщений ACM за октябрь 2000 г. В статьях в основном сравнивается объектно-ориентированный подход и процессно-ориентированный подход. Существует множество исследований того, как люди, работающие с ОО-методом, «думают» (Int. J. of Human-Computer Studies 2001, выпуск 54 или Human-Computer Interaction 1995, vol. 10 посвящена целой теме ОО-исследований). и из того, что я прочитал, нет ничего, что указывало бы на некоторую естественность объектно-ориентированного подхода, которая делает его более подходящим, чем более традиционный процедурный подход.

Svend
источник
18
Работает нормально. Чего он не может, так это заставить плохих программистов писать хороший код. По этой причине есть периодический оттенок и крик против этого.
хаос
6
@melaos: резюме находится посередине. ООП - это один из инструментов в наборе инструментов, а не единственный, и ничто не может заменить обучение, опыт и суждения.
Майк Данлэйви,
44
Я нахожу забавным, когда кто-то публикует «Вопрос», чтобы аргументировать свою точку зрения, а затем принимает первый ответ, который поддерживает его точку зрения, даже если есть вопросы с более высоким рейтингом, подтверждающие обратное. Человеческая природа крутая.
Bill K
3
@melaos, резюме (по крайней мере, этих статей) состоит в том, что ничто не предполагает, что объектно-ориентированный подход является естественным способом мышления для людей и, следовательно, не превосходит любой другой способ создания программ.
Svend
6
@Bill K: Это был один из немногих ответов, который содержал цитаты, а не размахивание руками и простое настаивание на том, что объектно-ориентированный подход "должен" быть лучше. Если упомянутая литература поддерживает идею о том, что объектно-ориентированный объект не является каким-либо конкретным улучшением или какой-либо конкретной пользой, и, следовательно, поддерживает мою исходную позицию, я не уверен, почему я должен игнорировать это. Можете ли вы предоставить аналогичные ссылки, которые противоречат моему OP?
DrPizza
119

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

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

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

Конрад Рудольф
источник
10
Мне показалось интересным, что здесь больше голосов, чем за вопрос и одобренный ответ вместе взятые.
Брэд Гилберт,
15
Я считаю, что система типов в Haskell намного более интуитивно понятна, чем объектно-ориентированная.
axblount
4
@Konrad: «но он делает крупномасштабные приложения намного проще» - хммм, я не уверен, что это правда. Это делает их более удобными в обслуживании в том смысле, что замена одного элемента не должна нарушать работу другого, а проще? Это град, чтобы проглотить ...
Митч Уит
2
@BradGilbert: конечно, спрашивающий выбрал ответ, который полностью совпадает с мнением в его первоначальном вопросе. Возникает вопрос: зачем вообще задавать этот вопрос, если вы уже определились со своим ответом?
ТМ.
2
@Mitch: Я бы даже сказал, что вы не можете (на сегодняшний день) писать крупномасштабные приложения без какой-либо объектной ориентации. Крупномасштабный здесь -> 1 млн LOC.
Конрад Рудольф,
45

ООП - это не создание повторно используемых классов, а создание полезных классов.

Брайан Лихи
источник
7
Хороший! И это правда.
Toon Krijthe
1
Справедливо. Но тогда это не решает проблему «изобретать колесо», которая, честно говоря, является серьезной в разработке программного обеспечения - вместо одной библиотеки, в которой есть N пар глаз, ищущих недостатки, у нас есть N библиотек с парой глаз, выполняющих так. Есть так много полезных классов, которые вы можете создать, прежде чем вам понадобится их повторно использовать. И ООП, по моему мнению, в корне ошибочен именно в этой области - повторном использовании кода. Он скрывает данные и «связывает» их с методами, что фактически делает эти данные недоступными или трудными для взаимодействия.
amn
42

Слишком часто класс используется просто из-за его синтаксического сахара; он помещает функции для типа записи в их собственное небольшое пространство имен.

Да, я тоже считаю, что это слишком распространено. Это не объектно-ориентированное программирование. Это объектно-ориентированное программирование и программирование, ориентированное на данные. За 10 лет работы с объектно-ориентированными языками я вижу людей, которые в основном занимаются объектно-ориентированным программированием. OBP ломается очень быстро IMHO, поскольку вы, по сути, получаете худшее из обоих слов: 1) процедурное программирование без соблюдения проверенной методологии структурированного программирования и 2) OOP без соблюдения проверенной методологии OOP.

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

Большинство разработчиков, работающих с языками ООП, используют примеры ООП, выполненные прямо в рамках и типах, которые они используют изо дня в день, но они просто не знают об этом. Вот несколько очень простых примеров: ADO.NET, Hibernate / NHibernate, Logging Frameworks, различные типы языковых коллекций, стек ASP.NET, стек JSP и т. Д. Все это вещи, которые сильно зависят от ООП в их кодовых базах.

Даниэль Аугер
источник
32

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

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

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

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

theschmitzer
источник
3
Верно, что повторное использование и объектно-ориентированный объект являются отдельными проблемами.
Дэн Розенстарк,
28

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

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

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

user2189331
источник
2
Я только что дал вам положительный голос, который поднял вас выше 2000 баллов - надеюсь, он останется. : P
Джейсон Бантинг
5
Редко можно увидеть эффективное обучение ООП.
Jon W
Ваш ответ очень похож на тот, который дают инструкторы Agile / Scrum на вопрос, имеет ли он смысл - «это очень полезно, если вы делаете это правильно; если вы терпите неудачу, значит, вы делаете это неправильно». Легко использовать такие слова, как «многоразовый» и «ремонтопригодный», но непросто количественно оценить эти качества в реальном коде, и нет рецепта, который бы сказал вам, как написать хорошее ООП (несмотря на тысячи книг, пытающихся это сделать) , У нас также появляется дурная привычка якобы игнорировать оборудование, что приводит к ужасной производительности на алтаре предотвращения преждевременной оптимизации.
Tom
21

Я думаю, что использование непрозрачных объектов контекста (HANDLEs в Win32, FILE * s в C, чтобы назвать два хорошо известных примера - черт возьми, HANDLEs живут по другую сторону барьера режима ядра, и это действительно не дает гораздо более инкапсулированный, чем это) также можно найти в процедурном коде; Я изо всех сил пытаюсь понять, почему это что-то особенное для ООП.

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

Видите ли, это проблема каждого отдельного обсуждения, связанного с ООП или альтернативными методами: никто не понимает определение, все говорят о чем-то другом, и поэтому невозможно достичь консенсуса. Мне кажется, это пустая трата времени.

Конрад Рудольф
источник
1
Я как раз собирался опубликовать что-то очень похожее.
Брэд Гилберт,
Я согласен с тем, что вы можете использовать концепции ООП без специального синтаксиса, но, с другой стороны, я не думаю, что WinAPI является хорошим примером концепций ООП.
Лена Шиммель
14

Это парадигма программирования ... Создана для того, чтобы нам, простым смертным, было проще разбивать проблему на более мелкие, работоспособные части ...

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

Я же считаю это полезным, так что буду :)

Роб Купер
источник
14

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

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

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

Высокий Джефф
источник
1
Повторное использование - это своего рода Грааль для разработчиков программного обеспечения, не так ли, независимо от того, какую парадигму они используют, будь то объектно-ориентированный подход, функциональность или что-то еще? Это вступает в противоречие с постоянно меняющимися требованиями, предъявляемыми к программному обеспечению, и, похоже, вопрос заключается в создании гибких дизайнов.
Geoglyph
«понятие класса, который отделяет интерфейс от реализации» --- я думал, что интерфейсы были интерфейсами, а классы - реализациями? Возможно, я просто слишком ориентирован на процесс, но я полагаю, что это полиморфизм, вариативность кода при единообразии в использовании, вот что главное в ООП; Я полагаю, что «набор функций C» отделяет интерфейс от реализации точно так же, как «класс java». Может я все не прав?
Йонас Кёлькер,
2
@Jonas - Для вашей «группы функций C» - я согласен, что они могут отделить интерфейс от реализации, и в этот момент он начинает быть ООП. Если в примере продолжается определение структуры C, с которой работает API, вы в основном создали инкапсуляцию (особенно если API непрозрачно работает со структурой) ... и тогда это действительно ООП в C.
Талл Джефф,
12

Проблема с ООП в том, что оно было перепродано.

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

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

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

Так что бы я сделал по-другому? Много, и я написал об этом книгу. (Это распечатано - я не получаю ни цента, но вы все равно можете получить копии.) Amazon

Мой конструктивный ответ - смотреть на программирование не как на способ моделирования вещей в реальном мире, а как на способ кодирования требований.

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

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

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

оборота Майк Данлэйви
источник
Прохладно. Поскольку книга больше не издается, вы бы не хотели предоставлять PDF-файлы, не так ли? Amazon МЕДЛЕННО отправляет в Аргентину ...
Дэн Розенстарк
Я подозреваю, что где-то в начале процесса некоторые хорошие программисты восхищались тем, что они могут делать с ООП, а кто-то подслушал их и подумал, что это означает, что каждый может и сделает то же самое.
хаос
@ Дэниел: хорошее предложение. Я поработаю над этим и посмотрю, смогу ли я прикрепить его к своему блогу. Вы найдете это немного старомодным, потому что это было в 94-м, но принципы не изменились.
Майк Данлэви, 01
1
@Mike Dunlavey Уважаемый сэр, могу ли я поддержать любопытство @ yar узнать, есть ли возможность прочитать / получить вашу книгу [хотя бы частично] через Интернет? Как кажется, способ эффективной спецификации / реализации [компонента] программного обеспечения, который вы предлагаете / разрабатываете, очень похож на тот, который [я недавно узнал], которому я хотел бы научиться или меня учили (в отличие от, ну, в общем, пути «груза», введенного красиво написанные, но до боли неоднозначные основные ОО-книги). Заранее спасибо [и приветствия из России :)].
mlvljr 01
1
@mlvljr: Хорошо. Самый быстрый способ - просто отсканировать его и создать большой PDF-файл. Я посмотрю, смогу ли я добраться до него в ближайшие несколько дней. Не дай мне забыть [искренние соболезнования в связи с недавними событиями в Москве и приветствия из сырого Массачусетса].
Майк Данлэйви, 01
11

РУЧКИ (и остальная часть WinAPI) - ООП!

Но есть ли они? Они не наследуются, они определенно не могут быть заменены, им не хватает четко определенных классов ... Я думаю, что они далеки от "ООП".

Вы когда-нибудь создавали окно с помощью WinAPI? Затем вы должны знать, что вы определяете класс ( RegisterClass), создаете его экземпляр ( CreateWindow), вызываете виртуальные методы ( WndProc) и методы базового класса ( DefWindowProc) и так далее. WinAPI даже берет номенклатуру из SmallTalk OOP, вызывая методы «сообщения» (Window Messages).

Ручки могут не передаваться по наследству, но есть finalв Java. Они не хватает класса, они являются заполнителем для класса: Это то , что слово «ручка» означает. Глядя на такие архитектуры, как MFC или .NET WinForms, сразу становится очевидным, что, за исключением синтаксиса, ничем особо не отличается от WinAPI.

Конрад Рудольф
источник
WINAPI - это не ООП. Он просто показывает способ написания расширяемого процедурного кода. Хорошие техники хороши независимо от того, являются они ООП или нет. Я могу писать программы WINAPI на C и использовать те же методы в моем собственном коде, поэтому я полагаю, что C - это ООП.
Брюсэтк
3
Возможно, это было не то, что имел в виду Алан Кей (погуглите!), Но тем не менее это ООП.
Конрад Рудольф
11

Да, ООП не решило всех наших проблем, извините за это. Однако мы работаем над SOA, которая решит все эти проблемы.

натуральный
источник
4
Ты не слышал? SOA - это прошлое. Сегодня именно облачные вычисления станут нашим спасителем.
DrPizza
Мне правда интересно, ироничны ваши ответы или нет. Мне нравится ирония, но обычно ее отвергают, и это заставляет меня задуматься ...
Лена Шиммель
Я думаю, что это ирония, и я не буду голосовать против. Но я тоже не буду голосовать за это! :-)
Ярик
Вопрос довольно риторический, так что это правильный ответ (и лучший ответ).
Джефф Дэвис,
10

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

Проблема в том, что 90% из нас работают в мире бизнеса, где мы работаем с такими бизнес-концепциями, как Счет-фактура, Сотрудник, Работа, Заказ. Они не так хорошо подходят для ООП, потому что «объекты» более расплывчаты, могут изменяться в соответствии с реорганизацией бизнеса и т. Д.

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

Тони Эндрюс
источник
Это все правда, но ... возможно, тот факт, что ООП может упростить НЕКОТОРЫЕ, не связанные с бизнесом аспекты приложения (например, реализацию пользовательского интерфейса), является одной из основных причин, по которым разработчик (наконец-то!) Может тратить больше времени на работу над бизнесом. -связанные аспекты?
Ярик
10

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

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

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

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

оборота иселава
источник
1
Я никогда не достигал фазы чистого удовольствия процедурно или без использования ООП при чтении кода. :)
bruceatk
1
Чистая радость, нет, но, может быть, легкая улыбка?
Дэн Rosenstark
9

Может быть, чепчик, колени или дерево - это не стул, но все они доступны.

Джонно Нолан
источник
2
Вам никогда не приходилось использовать объектно-ориентированный язык без интерфейсов? Ты счастливчик.
finnw
Нет, это не так. Это вещи, которые не были предназначены для сидения, поэтому я думаю, чтобы быть верным аналогии, они не были бы написаны для реализации интерфейса ISittable. Они взяты из сторонней библиотеки, и теперь, когда вы пишете проект, включающий домен, который включает сидение, вы обнаружите, что вам придется написать объекты адаптера, чтобы обернуть их, чтобы сделать их ISittable. Видеть? Не очень похоже на реальный мир.
EricS
8

Я думаю, что эти вещи в реальном мире - объекты

Вы делаете?

Какие методы есть у инвойса? Ой, подожди. Он не может оплатить сам себя, он не может отправить сам себя, он не может сравнить себя с товарами, которые фактически доставил поставщик. У него вообще нет никаких методов; это совершенно инертно и нефункционально. Это тип записи (структура, если хотите), а не объект.

Точно так же и другие вещи, о которых вы говорите.

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

DrPizza
источник
2
Возьмите любую машину, электронное устройство или живое существо - все это «взаимосвязь состояния и поведения».
ТМ.
1
Я согласен с тем, что такие методы, как Send () или Pay (), "неестественны" для счетов. Но, например, как насчет общей суммы как производного, но ВНУТРЕННЕГО атрибута счета-фактуры? Разве это не пример того, что ООП позволяет моделировать очень "естественным" способом даже для полностью инертных реальных объектов? Само по себе не большое достижение, но все же ...
Ярик
@Yarik: Эти «инертные» сущности приводят к объектно-ориентированному дизайну. Для меня единственный правильный объектно-ориентированный объект - это моделирование, где объекты «могут действовать сами по себе» , как говорится в этом ответе. Если объектно-ориентированный подход - единственный способ добиться чего-то, прекрасно, но разве мы не можем придерживаться чего-то более простого и больше похожего на решаемую проблему?
7

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

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

Шон Кирон
источник
7

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

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

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

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

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

Дэвид Торнли
источник
Мне больше всего нравится твой последний абзац.
Майк Данлэви,
6

@Sean

Однако выделение общей функциональности в базовый класс, а затем повторное использование ее в других классах-потомках - это очень элегантная вещь, ИМХО!

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

DrPizza
источник
6

@Konrad

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

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

DrPizza
источник
6

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

Не обязательно имеет значение, что счет-фактура на самом деле не является «объектом» с функциями, которые он может выполнять сам - экземпляр объекта может существовать только для выполнения функций с данными без необходимости знать, какой тип данных на самом деле существует. Функцию invoice.toJson () можно успешно вызвать без необходимости знать, что это за данные «счет-фактура» - результатом будет Json, независимо от того, исходит ли он из базы данных, XML, CSV или даже другого объекта JSON. , С процедурными функциями вы внезапно должны узнать больше о своих данных и в конечном итоге получите такие функции, как «xmlToJson ()», «csvToJson ()», «dbToJson ()» и т.д. ОГРОМНАЯ головная боль, если вы когда-нибудь измените базовый тип данных.

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

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

Вэнс Лукас
источник
5

@CodingTheWheel

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

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

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

DrPizza
источник
«Правильная тренировка» в наши дни должна быть очень длинной, абстрактной и сложной. Знаю: преподаю программирование. Десятилетия назад многие люди могли научиться программировать. Я думаю, что это уже не так.
5

@Джефф

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

Что имеет более скрытую реализацию: iostreams C ++ или FILE * s?

Я думаю, что использование непрозрачных объектов контекста (HANDLEs в Win32, FILE * s в C, чтобы назвать два хорошо известных примера - черт возьми, HANDLEs живут по другую сторону барьера режима ядра, и это действительно не дает гораздо более инкапсулированный, чем это) также можно найти в процедурном коде; Я изо всех сил пытаюсь понять, почему это что-то особенное для ООП.

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

DrPizza
источник
5

В единственном блоге разработчиков, который я прочитал, этот парень Joel-On-Software-Founder-of-SO давным-давно прочитал, что объектно-ориентированный подход не приводит к увеличению производительности. Автоматическое управление памятью делает. Прохладно. Кто может опровергнуть данные?

Я по-прежнему считаю, что объектно-ориентированное программирование для не-объектно-ориентированного программирования - то же самое, что программирование с функциями для программирования всего встраиваемого.

(И я должен знать, поскольку я начал с GWBasic.) Когда вы реорганизуете код для использования функций, он variable2654становится variable3методом, которым вы пользуетесь . Или, еще лучше, у него есть имя, которое вы можете понять, и если функция короткая , он называется, value и этого достаточно для полного понимания.

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

Когда вы реорганизовывать код , чтобы быть действительно OO, b, c, q, и Zстать this, this, thisи this. А поскольку я не верю в использование этого thisключевого слова, вы можете удалить мили кода. Фактически, вы можете это сделать, даже если используете this.



Я не думаю, что объектно-ориентированный объект - естественная метафора.

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

Например, когда вы используете систему бронирования авиабилетов, то, что вы называете бронированием, может вообще не соответствовать юридическому / бизнес-бронированию.



Некоторые из основных концепций - действительно крутые инструменты

Я думаю, что большинство людей преувеличивают, говоря «когда у вас есть молоток, они все гвозди». Я думаю, что и обратная сторона медали / зеркала так же верна: когда у вас есть гаджет, подобный полиморфизму / наследованию, вы начинаете находить применения, которые подходят, например, перчатка / носок / контактная линза. Инструменты OO очень мощные. Я думаю, что одинарное наследование абсолютно необходимо для того, чтобы люди не увлекались, несмотря на мою собственную программу множественного наследования.



В чем смысл ООП?

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

ООП суждено быть неправильно понятым большинством разработчиков

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



По поводу вашего мини-эссе / вопроса

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

Если вы попросите начинающих программистов написать элемент управления календарем, они часто думают про себя: «О, я собираюсь написать лучший в мире элемент управления календарем! Он будет полиморфным по отношению к типу календаря. У него будут средства отображения, и мунджеры, и то, и то, и другое ". Им нужно отправить календарное приложение в течение двух месяцев. Они помещают всю эту инфраструктуру в систему управления, а затем тратят два дня на написание дрянного календаря поверх нее. Они будут думать: «В следующей версии приложения я сделаю гораздо больше».

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

Яр
источник
4

Вы когда-нибудь создавали окно с помощью WinAPI?

Больше раз, чем я могу вспомнить.

Затем вы должны знать, что вы определяете класс (RegisterClass), создаете его экземпляр (CreateWindow), вызываете виртуальные методы (WndProc) и методы базового класса (DefWindowProc) и так далее. WinAPI даже берет номенклатуру из SmallTalk OOP, вызывая методы «сообщения» (Window Messages).

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

Дескрипторы могут не передаваться по наследству, но в Java есть final. У них нет класса, они заменяют его: вот что означает слово «дескриптор». Глядя на такие архитектуры, как MFC или .NET WinForms, сразу становится очевидным, что, за исключением синтаксиса, ничем особо не отличается от WinAPI.

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

Это правда? Лучшие части ООП - это просто ... традиционный процедурный код? Это большое дело?

DrPizza
источник
Вы должны помнить, что интерфейс Win32 был в основном переопределением Win16. Который был разработан более двух десятилетий назад.
Брэд Гилберт,
Когда я учился программировать в колледже, в основном на C, но также и на некоторых других языках, нас научили некоторым основным идеям и познакомили с несколькими платформами, но было понятно, что общая ответственность за разработку дизайна, фреймворков, лучших практик, и т.д. будет зависеть от нас на рабочем месте. Мы изучили техники, а не мировоззрения. С помощью объектно-ориентированного подхода вы должны изучить религию, прежде чем сможете делать что-нибудь полезное, и это полностью определяет, как вы видите решения. Я не думаю, что это действительно правильно.
4

Я полностью согласен с ответом InSciTek Jeff , я просто добавлю следующие уточнения:

  • Скрытие и инкапсуляция информации: критично для любого поддерживаемого кода. Это можно сделать, проявив осторожность в любом языке программирования, не требует функций объектно-ориентированного программирования, но при этом ваш код будет немного похож на объектно-ориентированный.
  • Наследование: Существует одна важная область применения , для которых все те ОО является в своем роде, из и содержит, а отношения идеально подходят: Графические интерфейсы пользователя. Если вы попытаетесь создать графический интерфейс без поддержки языка OO, вы все равно создадите OO-подобные функции, а без языковой поддержки это сложнее и подвержено ошибкам. Например, Glade (недавно) и X11 Xt (исторически).

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

ревизии Людвикас Букис
источник
Да, я думаю, вы должны использовать ООП для объектов, функциональное программирование для функций ...
Сванте
4

Я считаю, что наиболее выгодным качеством ООП является скрытие / управление данными. Однако есть МНОГО примеров неправильного использования ООП, и я думаю, что здесь и возникает путаница.

То, что вы можете превратить что-то в объект, не означает, что вы должны это делать. Однако, если это сделает ваш код более организованным / легким для чтения, вам определенно следует это сделать.

Отличный практический пример, когда ООП очень полезен, - это класс «продукта» и объекты, которые я использую на нашем веб-сайте. Поскольку каждая страница является продуктом, и каждый продукт имеет ссылки на другие продукты, может возникнуть путаница в отношении того, к какому продукту относятся данные. Является ли эта переменная strURL ссылкой на текущую страницу, или на домашнюю страницу, или на страницу статистики? Конечно, вы можете создать всевозможные переменные, которые ссылаются на одну и ту же информацию, но proCurrentPage-> strURL намного легче понять (для разработчика).

Кроме того, добавление функций к этим страницам намного проще. Я могу сделать proCurrentPage-> CleanCache (); Затем следует proDisplayItem-> RenderPromo (); Если бы я просто вызвал эти функции и предположил, что текущие данные доступны, кто знает, какое зло произойдет. Кроме того, если бы мне пришлось передать правильные переменные в эти функции, я вернулся бы к проблеме наличия всевозможных переменных для различных продуктов.

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

Тем не мение. Большая проблема с ООП - это когда кто-то считает, что ВСЕ должно быть ООП. Это создает массу проблем. У меня в базе 88 таблиц. У меня всего около 6 классов, а может быть, около 10. Мне точно не нужно 88 классов. В большинстве случаев прямой доступ к этим таблицам вполне понятен в тех обстоятельствах, в которых я его использую, и ООП фактически усложнит / утомит доступ к основным функциям того, что происходит.

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

Джефф Дэвис
источник
3

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

И OO - чертовски эффективный способ сделать ваши программы удобочитаемыми. Повторное использование или отказ от повторного использования.

Фредерик Дурак
источник
2

"Реальный мир - это не" OO ","

В самом деле? Мой мир полон предметов. Я использую один сейчас. Я думаю, что наличие программных «объектов», моделирующих реальные объекты, не так уж и плохо.

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

С. Лотт
источник
2

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

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

Внедрение объектно-ориентированного программирования в язык просто дает программисту еще одно средство выражения.

Самая большая часть написания кода - это не общение с машиной, эта часть проста, самая большая часть - это общение с людьми-программистами.

Бернар Игири
источник