Возможно, самое большое обещание использования объектно-ориентированной парадигмы - это повторное использование кода. Некоторые оспаривают, что это было достигнуто. Почему это было (не) достигнуто?
Позволяет ли повторное использование кода, как его определяет ООП, сделать проекты более продуктивными?
Или более управляемым? Или проще в обслуживании? Или с большим качеством?
Вероятно, мы все согласны с тем, что повторное использование кода - это хорошо, но есть несколько способов достичь этой цели. Вопрос о способе повторного использования кода, предложенном ООП. Это было хорошо? Существуют ли лучшие методы для повторного использования кода, чем объектная ориентация, подклассификация, полиморфизм и т. Д.? Какие способы лучше? Почему ?
Расскажите нам о своем опыте повторного использования ООП или других парадигм.
Ответы:
Повторное использование кода довольно хорошая идея. Не большой один .
У меня есть перспектива, извлеченная из 30-летнего опыта разработки программного обеспечения, пытающегося «повторно использовать».
Я начал исследовать «повторное использование кода» в качестве темы исследования еще в 80-х годах, когда обнаружил, что повторно использовал дизайн одной ОС, созданной в начале 70-х годов, для другой ОС, которую я создал в конце 70-х годов.
Хорошей частью повторного использования кода является возможность иногда повторно использовать честный ранее существовавший код. Но мир полон кода; как найти то что хочешь? Вот что я называю проклятием повторного использования :
Я Санта-Клаус (хорошо с открытым исходным кодом), и у меня есть пакет из 1 миллиарда программных компонентов. Вы можете иметь любой из них.
Удачи в выборе.
Чтобы решить проблему повторного использования хорошо:
Главным образом то, что было обнаружено за эти годы, заключается в том, что для того, чтобы код можно было многократно использовать, он должен быть спроектирован для этой цели или содержит слишком много неявных допущений. Самые успешные библиотеки повторного использования кода были довольно маленькими. Возможно, библиотеки и фреймворки представляют собой «повторно используемый» код, и они чрезвычайно успешны; Java и C # достигают успеха не потому, что они являются довольно хорошими компьютерными языками, а потому, что они имеют огромные хорошо разработанные, реализованные и документированные доступные библиотеки. Но люди не смотрят на исходный код в библиотеках; они просто вызывают хорошо документированный API (предназначенный для общего пользования).
То, что повторное использование кода еще не сделало (и ООП), - это улучшение порядка наших возможностей для систем кодирования.
Я думаю, что ключевым недостатком является то, что любое повторное использование кода принципиально ограничено, потому что в коде слишком много встроенных допущений . Если вы делаете код крошечным, вы сводите к минимуму допущения, но тогда затраты на сборку с нуля не очень велики, а выгоды от повторного использования неэффективны. Если вы сделаете куски кода огромными, они в значительной степени бесполезны в новом контексте. Как и Гулливер, они привязаны к пляжу миллионами крошечных ниточек, и вы просто не можете позволить себе разрезать их все.
То, над чем мы должны работать, это повторное использование знаний для создания кода . Если мы сможем сделать это, то сможем применить эти знания для создания необходимого кода, обрабатывая текущий набор предположений.
Чтобы сделать это, все еще нужна та же спецификационная возможность для характеристики программных компонентов (вы все равно должны сказать, что хотите!). Но затем вы применяете эти «конструкторские» знания к спецификациям, чтобы сгенерировать нужный код.
Как сообщество, мы еще не очень хороши в этом. Но люди делают это все время; почему мы не можем автоматизировать это? Есть много исследований, и это показывает, что это может быть сделано при многих обстоятельствах.
Одним из ключевых механизмов, необходимых для этого, являются механические инструменты для принятия «описаний компонентов» (это просто формальные документы и могут быть проанализированы как языки программирования) и применения к ним программных преобразований .
Компиляторы уже делают это: -} И они действительно хороши в классе задач, которые они решают.
Модели UML с генерацией кода являются одной из попыток сделать это. Не очень хорошая попытка; почти все, что говорят в большинстве моделей UML: «У меня есть данные, которые выглядят так». Довольно сложно создать настоящую программу, если ее функциональность не учитывается.
Я пытаюсь создать практические системы преобразования программ, инструмент под названием DMS . Очень хорошо отвлекся, применяя программные преобразования не столько к абстрактным спецификациям для генерации кода, сколько к устаревшему коду для его очистки. (Это та же проблема в резюме!). (На создание таких инструментов уходит много времени; я занимаюсь этим уже 15 лет, а пока вы должны есть).
Но у DMS есть два ключевых свойства, которые я описал выше: способность обрабатывать произвольные формальные спецификации и способность собирать «знания о генерации кода» в виде преобразований и применять их по требованию. И что примечательно, в некоторых особых случаях мы генерируем довольно интересный код из спецификаций; DMS в значительной степени построен с использованием самого себя для генерации своей реализации. Это дало нам, по крайней мере, некоторые возможности многократного использования (знаний): чрезвычайно значительное повышение производительности. У меня есть команда из около 7 технических специалистов; мы написали, вероятно, 1-2 MSLOC «спецификаций» для DMS, но у нас есть 10MSLOC сгенерированного кода.
Резюме: повторное использование знаний поколения - это победа, а не повторное использование кода .
источник
Mostly what has been discovered over the years is that for code to be reusable, it sort of has to be designed for that purpose, or it contains too many implicit assumptions.
Я пришел к аналогичному выводу, но не смог выразить это так кратко.Повторное использование кода достигается в ООП, но также и в функциональном программировании. Каждый раз, когда вы берете блок кода и делаете его доступным для остального кода, так что вы можете использовать эту функцию в другом месте, это повторное использование кода.
Этот тип повторного использования кода также делает код более управляемым, потому что изменение этого одного вызываемого блока изменяет все места, которые он вызывает. Я бы сказал, что этот результат также повысил качество и читабельность.
Я не уверен, что ООП просто обеспечивает повторное использование кода. Я рассматриваю ООП как способ взаимодействия с объектами и абстрагирования от деталей структуры данных.
Из Википедии:
источник
double sqrt (double x)
? Чистые функции являются архетипом повторного использования.double sqrt(double x)
,float sqrt(float x)
,int sqrt(int x)
вы можете определить их много, в то время как с Generic языка программирования вы быNumber sqrt(Number x)
и сделать с ней.И да и нет
Повторное использование кода является универсальным термином для многих различных видов деятельности.
источник
Я бы написал длинный ответ, но почему? Уди Дахан объясняет это гораздо лучше, чем я.
http://www.udidahan.com/2009/06/07/the-fallacy-of-reuse/
Вот начало поста:
источник
Я согласен с Крисом, функциональное программирование - это хороший способ повторного использования кода.
Многие программы имеют повторяющиеся структуры кода. Для этого в мире ООП используются некоторые шаблоны проектирования , но этого можно достичь с помощью рекурсивных функций и сопоставления с образцами в функциональных языках программирования. Подробнее об этом см. В первой главе «Функциональное программирование в реальном мире» .
Я думаю, что глубокое наследование в ООП может вводить в заблуждение во многих случаях. У вас есть класс, и многие тесно связанные методы реализованы в разных файлах. Как сказал Джо Армстронг об ООП:
Функции высокого порядка также очень полезны, когда речь идет о повторном использовании кода, например,
map
иfoldr
это является основой Google MapReduce .Асинхронная передача сообщений также является хорошим способом организации сложного программного обеспечения, и некоторые компьютерные ученые утверждают, что предполагается, что объекты взаимодействуют друг с другом асинхронно, как в сообщении Tell, не задавайте принцип ООП. Узнайте больше об этом в объектно-ориентированном программировании: неправильный путь? где Джо Армстронг цитируется:
Асинхронная передача сообщений, как в системах, управляемых событиями, так и в Erlang, также является очень хорошим способом разъединения систем, а слабая связь важна в сложных системах. С достаточно отделенной системой вы можете развивать систему, пока она работает, возможно, на разных узлах. Unibet сделал отличную презентацию об этом: архитектура, управляемая событиями домена
Однако я думаю, что большая часть повторного использования кода выполняется с использованием библиотек и сред.
источник
Скромный канал Unix сделал больше для повторного использования кода, чем все остальное, что приходило и уходило. Объекты просто оказались интуитивно понятным способом структурирования кода, когда они появились, и позже люди начали привязывать все и вся к нему. В общем случае объекты предназначены для инкапсуляции, а не для повторного использования кода, повторное использование кода требует чего-то большего, и иерархия наследования классов является плохой заменой того, каким должен быть механизм повторного использования кода.
источник
ООП не особенный; Вы можете сделать код многократного использования с или без ООП. Чистые функции особенно пригодны для повторного использования : например,
java.lang.math.sqrt(double)
принимает число и выдает число. Нет ООП, но определенно более пригодно для повторного использования, чем большая часть кода.источник
С точки зрения функционального программирования ООП в основном касается управления состоянием.
В функциональном программировании вы можете легко иметь сотни полезных функций для списков: http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Data-List.html .
У вас были бы сотни методов в классе List? Публичные методы считаются интерфейсом для внутреннего состояния, которое вы хотите сохранить небольшим.
К сожалению, вместо (повторного) использования множества мелких функций некоторые люди дублируют функциональность. Для меня это потому, что ООП не поощряет повторное использование кода так, как это делает функциональное программирование.
источник
Для меня да, но не все время, и это можно было бы сделать другими способами.
Большую часть времени создавая абстрактный базовый класс и создавая конкретные реализации этого класса.
Также многие фреймворки используют наследование для повторного использования кода (Delphi, Java, .Net - это только некоторые из них, которые приходят на ум сразу).
Это не значит, что многие служебные библиотеки и фрагменты кода также не справились бы с этой задачей, но есть кое-что приятное в хорошо спроектированной иерархии объектов.
источник
По моему опыту, я добился большего успеха, используя «многократно используемый» код через универсальные средства программирования (такие как шаблоны C ++), чем используя принципы ООП, такие как иерархии наследования.
источник
ООП слишком открыт для эффективного повторного использования.
Есть слишком много способов для повторного использования. Каждый публичный класс спрашивает: «Сделай меня новым экземпляром!» каждый публичный метод говорит: "позвони мне!" , каждый защищенный метод выдает: "переопределить меня!" - и все эти способы повторного использования различны , у них разные параметры, они появляются в разных контекстах, у всех свои правила, как вызывать / расширять / переопределять его.
API лучше, это строгое подмножество точек OOP (или неопций), но в реальной жизни API переоценены и постоянно растут, все еще слишком много точек подключения. Кроме того, хороший API может облегчить жизнь, это лучший способ предоставить интерфейс для ООП.
Парадигма Datadlow обеспечивает строгий интерфейс для компонентов, они имеют порты следующих типов:
Зависит от домена, есть несколько типов пакетов, поэтому потребители и производители могут быть подключены, если у них одинаковые (или совместимые) порты. Самая красивая часть этого - то, что это может быть сделано визуально, потому что нет никаких параметров или каких-либо других настроек соединений, они действительно просто соединяют потребителя и производителя.
Я был немного неясен, вы можете посмотреть на «поток данных» метки на StackOverflow или Википедии «datafow программирования» или Википедии « на основе потоков программирования» .
(Кроме того, я написал систему потоков данных на C ++. Так что OOP и DF не враги, DF - это организация более высокого уровня.)
источник
В CommonLisp есть много способов добиться повторного использования:
динамическая типизация, при которой ваш код будет универсальным по умолчанию
императивные абстракции, то есть подпрограммы
объектно-ориентированная, с множественным наследованием и множественной диспетчеризацией
Синтаксическая абстракция, способность определять новые синтаксические конструкции или сокращать стандартный код
функциональные абстракции, замыкания и функции высокого порядка
Если вы попытаетесь сравнить работу CommonLisp с другими языками, вы увидите, что основной функцией, облегчающей повторное использование кода, является наличие как объектно-ориентированных, так и функциональных абстракций. Они более дополняют друг друга, чем альтернативные: без одного из них вы вынуждены неуклюже переопределять отсутствующие функции. См., Например, классы функторов, используемые как замыкания и сопоставление с образцом для получения нерасширяемой диспетчеризации метода.
источник
- Кевлин Хенни
источник
Я рискну высмеять и признаться, я только недавно использовал ООП. Это не приходит ко мне автоматически. Большая часть моего опыта связана с реляционными базами данных, поэтому я думаю о таблицах и объединениях. Есть утверждения, что лучше изучать это с самого начала, чтобы избежать необходимости менять мышление, когда дело доходит до программирования. У меня нет такой роскоши, и я отказываюсь отказаться от своей карьеры из-за какой-то теории о башне из слоновой кости. Как и все остальное, я разберусь.
Сначала я думал, что вся концепция не имеет смысла. Это просто казалось ненужным и слишком большим количеством проблем. Я знаю, это безумный разговор. Очевидно, что требуется определенный уровень понимания, прежде чем вы сможете оценить преимущества чего-либо или отклонить его за лучшие методы.
Повторное использование кода требует готовности не повторять код, понимания того, как его выполнить, предварительного планирования. Следует ли вам избегать повторного использования кода, когда вы решили, что у вас есть случай, когда он просто не стоит? И ни один язык не является настолько строго ОО, что он выдаст ошибку, когда решит, что вы должны были унаследовать код от другого класса. В лучшем случае они обеспечивают среду, способствующую его реализации.
Я думаю, что наибольшим преимуществом ООП является общее признание того, как должен быть организован код. Все остальное - соус. Команда программистов может не полностью согласиться с тем, как все классы должны быть структурированы, но они должны быть в состоянии найти код.
Я видел достаточно процедурного кода, чтобы знать, что он может быть где угодно, а иногда и везде.
источник
ООП дает вам больше способов повторно использовать код. Вот и все.
источник
Горизонтальное повторное использование: аспекты, черты, трансплантаты
Классическая ОО иногда не подходит для повторного использования кода, особенно когда вы сводите с ума все наследование из-за отсутствия лучшего способа обмена фактической функциональностью между классами. Для этой проблемы были созданы горизонтальные механизмы повторного использования, такие как AOP, черты и трансплантаты.
Аспектно-ориентированное программирование
Я рассматриваю АОП как недостающий пол-апельсин ООП. AOP на самом деле не так известен, но он сделал это для производственного кода.
Я попытаюсь объяснить это в простых терминах: представьте, что вы можете внедрить и отфильтровать функциональность с помощью специальной структуры, называемой аспектом, эти аспекты имеют «методы», которые определяют, что и как будет затронуто через отражение , но во время компиляции этот процесс называется ткачеством .
Примером может служить аспект, который говорит, что «для всех методов определенных классов, начинающихся с get, ваша программа запишет в файл журнала полученные данные и время их получения».
Посмотрите эти два доклада, если вы хотите лучше понять АОП:
Черты и прививки
Черты - это еще одна конструкция для определения кода многократного использования, который дополняет ООП, они похожи на миксины , но чище.
Вместо того, чтобы объяснять их, есть отличный PHP RFC, который объясняет оба . Черты приходят к PHP между прочим, они уже переданы в транк.
В итоге
ООП является ключевым в модульности, все же, на мой взгляд, и, как мы обычно знаем сегодня, ООП все еще не завершена .
источник
ООП Предоставляет набор полезных инструментов, которые позволяют писать код, который можно использовать в большем количестве мест, чем без этих инструментов. Если вы напишите
PrintIt
функцию, которая принимает какой-либо старый объект и вызывает.toString()
его, вы будете повторно использовать этот код, как только вы вызовете его с более чем одним типом объекта. С этими инструментами каждая строка кода делает больше.Функциональное программирование сейчас очень популярно среди хипстеров. Он предоставляет вам целый набор инструментов, чтобы каждая строка кода делала больше. Это, вероятно, не лучше или работает, но предоставляет другой инструмент в наборе инструментов.
(Была сумасшедшая идея для целого дополнительного уровня объектно-ориентированного повторного использования: идея заключалась в том, чтобы мы могли определить один
Customer
класс и использовать его в каждом приложении, которое мы написали. не сработало. Но это не означает, что OO Failed или даже повторное использование не удалось. Основные типы повторного использования кода в приложениях позволили писать приложения, которые сделали больше, и писать их быстрее.)источник
Читая вышеприведенные посты, несколько замечаний:
источник
Проблема более тонкая, имхо:
Так что ООП само по себе неплохо с точки зрения создания кода для повторного использования , но виды кода, которые пишутся с использованием ООП, по своей сути сложно использовать повторно .
Кроме того, функциональное программирование может привести к получению более многократно используемого кода . Но получить правильные абстракции для написания нормального функционального кода при соблюдении крайнего срока может оказаться невозможным. А «полуправые» абстракции будут проще выражать в стиле ООП. И это не приведет к более простому повторному использованию кода - более высокий уровень абстракций означает, что понимание кода потребует более высоких предварительных инвестиций из-за ограниченной познавательной способности программистов.
В качестве практического примера: игровой код включает в себя множество изменяемых состояний, потому что это естественный способ думать о кодировании игры, если только она не очень загадочная / алгоритмическая, поэтому она, очевидно, в конечном итоге структурируется с использованием ОО. И, конечно, это трудно использовать повторно. Но тот же код, содержащий те же знания, было бы еще сложнее использовать без ООП . И для того, чтобы переписать его в функциональный стиль, может потребоваться полное изменение того, как вы думаете об этом коде, знаниях, стоящих за ним. Да, полученные знания в коде станут намного понятнее после переписывания OO в FP, может быть ... но стоимость может быть огромной, и это может бытьтакая цена также должна быть оплачена людьми, желающими повторно использовать невероятно умный и хорошо абстрагированный код, с которым вы в конечном итоге сталкиваетесь , поэтому, как это ни парадоксально, люди в конечном итоге не будут повторно использовать код, даже если технически его можно будет использовать повторно.
... что приводит к последней тонкости: повторное использование кода связано с интерфейсом People | Code , а не только с кодом. ООП неплохо справляется с обслуживанием этого интерфейса, потому что он хорошо отображает, как много людей думают о многих видах кода, написанных в настоящее время. FP может быть лучше для повторного использования кода, но не для простого повторного использования вида кода, который люди действительно должны писать в настоящее время. Это изменится как вид кода, который нам нужен, чтобы написать изменения.
PS И если кто-то захочет сказать, что «ОО не является изменяемым состоянием, вы также можете иметь ОО с неизменяемым состоянием» ... Я называю это «FP, использующий классы в качестве пространств имен». Замечательно, когда он работает для вас, и он позволяет избежать некоторых недостатков модульных систем некоторых языков и может привести к более повторному использованию кода. Но это не ОО;)
источник