Преимущества объектно-ориентированного программирования [закрыто]

softwareengineering.stackexchange https://softwareengineering.stackexchange.com/questions/7126

  •  16-10-2019
  •  | 
  •  

Вопрос

Примечание:этот вопрос представляет собой отредактированный отрывок из публикация в блоге Я написал несколько месяцев назад.После размещения ссылки на блог в комментарий на Programmers.SE кто-то попросил меня опубликовать здесь вопрос, чтобы они могли на него ответить.Эта публикация — моя самая популярная, так как люди, похоже, вводят в Google «Я не разбираюсь в объектно-ориентированном программировании». много.Не стесняйтесь ответить здесь или в комментариях на Wordpress.

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

Может ли кто-нибудь поделиться со мной своим мнением о преимуществах объектно-ориентированного программирования?

Это было полезно?

Решение

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

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

Вот что такое процедурное программирование.

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

Что касается преимуществ объектно-ориентации по сравнению с не ориентированным на объект программного обеспечения:

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

Другие советы

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

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

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

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

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

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

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

РЕДАКТИРОВАТЬ:В ответ на вопрос Джоэла в комментариях:

Можете ли вы объяснить, что содержит «объектно-ориентированная программа» (кроме тех причудливых определений, которые вы обрисовали), которая принципиально отличается от императивной программы?Как вы «заставляете мяч двигаться?»

Здесь небольшая оговорка.Моя модель «объектно-ориентированной программы» — это, по сути, модель Delphi, которая очень похожа на модель C#/.NET, поскольку они были созданы бывшими членами команды Delphi.То, что я говорю здесь, может не применяться или не применяться в такой степени к другим объектно-ориентированным языкам.

Объектно-ориентированная программа — это программа, в которой вся логика структурирована вокруг объектов.Конечно, это должно быть где-то загружено.Ваша типичная программа Delphi содержит код инициализации, который создает одноэлементный объект с именем Application.В начале программы он вызывает Application.Initialize, затем вызов Application.CreateForm для каждой формы, которую вы хотите загрузить в память с самого начала, а затем Application.Run, который отображает основную форму на экране и запускает цикл ввода/событий, который составляет ядро ​​любых интерактивных компьютерных программ.

Приложение и ваши формы опрашивают входящие события из ОС и преобразуют их в вызовы методов вашего объекта.Одна вещь, которая очень распространена, — это использование обработчиков событий или «делегатов», как говорят в .NET.У объекта есть метод, который написал: «Делай х и ты, но также проверишь, чтобы увидеть, назначен ли этот конкретный обработчик событий, и назовите его, если это так». Обработчик событий-это указатель метода-очень простое закрытие, которое содержит ссылку на метод и ссылку на экземпляр объекта-которое используется для расширения поведения объектов.Например, если в моей форме есть объект кнопки, я настраиваю его поведение, присоединяя обработчик событий OnClick, который заставляет какой-либо другой объект выполнять метод при нажатии кнопки.

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

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

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

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

Я не уверен, что они когда -нибудь встроили это в Фортран, но это легко сделать в C и его потомках.

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

Есть различные виды систем OO, и трудно получить определение, с которым все согласятся. Вместо того, чтобы попытаться показать, как oo ooma oom -of Java похожа на общую систему объектов LISP, я начну с чего -то более обычного, шаг за шагом.

Предположим, у вас есть много объектов, существующих в виде рассеянных данных. Например, точки могут быть элементами в x, y и z массив. Чтобы рассмотреть саму точку, имеет смысл объединить все данные в нечто вроде C struct.

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

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

Основное преимущество заключается в наследстве и полиморфизме. Определяя все эти различные формы как подклассы класса, называемого Shape, мы можем манипулировать нашим кодом ShapeS, и это задача Ship Subobjects делать все, что требуется манипуляциями. Это означает, что нам не нужно касаться старого тестируемого кода, когда мы добавляем новые формы или уточняем поведение более старых. У нас автоматически есть старый код, который может напрямую использовать новый код. Вместо того, чтобы осознавать контрольный код обо всех различных возможных формах и необходимости поддерживать функции, которые знают обо всех различных формах Shape подклассы. Это упрощает контрольный код.

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

ОО имеет много разных определений, да. Я уверен, что вы можете найти много этого самостоятельно. Мне лично нравится Rees Re: oo как способ понять их. Я предполагаю, что вы уже прочитали это с тех пор, как вы цитируете Пола Грэма. (Я рекомендую это всем, кто интересуется OO.) Я собираюсь более или менее принять определение Java здесь {1,2,3,7,8,9}.

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

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

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

Java-ish OO-это полпути для этих проблем, которое, как оказалось, выиграло конкурс популярности. Поскольку это тот же механизм, который люди Java применяют к небольшим проблемам, создаваемым недостаточным языком, он начинает напоминать больше как волшебное решение для всего, чем просто способ оставаться организованным. Люди, знакомые с функциональным программированием, как правило, предпочитают другие решения, такие как классы типов Clos или Haskell, или шаблон метапреграммирования, когда застряли в C ++, или иначе (как и я, ежедневно работая в C#), но не все это волнует по этому поводу Анкет

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

  • Человек является объектом. У человека есть некоторые свойства, такие как возраст и пол. Человек может что -то делать: есть, спать, водить машину.
  • Автомобиль также является объектом (хотя иного типа). У этого также есть такие свойства, как Make, Model и год. Автомобиль может делать что -то: двигаться.

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

OOP = Структуры данных + передача сообщения + наследование, все из которых являются логическими эволюциями в моделях программирования.

ООП можно понять (программисты) примерно за 90 секунд (см. Мой профиль для ссылки). Концепции очень просты.

Как применить это другое дело. То, что вы знаете, как качать молот, не означает, что вы знаете, как проектировать и построить дом. ;-)

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

То, как я впервые понял это:

Перед объектно-ориентированным программированием у вас были Структурированное программирование. Анкет Все сосредоточено вокруг процесса. Первый вопрос, который вы должны задать себе, - это "Что я хочу делать с информацией?".

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

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

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

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

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

Я думаю, что страница в Википедии - хорошее место для получения основ:
http://en.wikipedia.org/wiki/object-oriented_programming

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

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

Надеюсь, это поможет. Просто продолжайте читать об этом и смотреть на код, и он внезапно будет «щелкнуть». Это был мой опыт.

Лицензировано под: CC-BY-SA с атрибуция
scroll top