Практическое использование ООП
У меня недавно была дискуссия с коллегой, который не является поклонником ОП. Мое внимание привлекло то, что он сказал:--3-->
" какой смысл делать мое кодирование в объектах? Если это повторное использование, я могу просто создать библиотеку и вызвать любые функции, которые мне нужны для любой задачи. Нужны ли мне эти понятия полиморфизма, наследования, интерфейсов, паттернов или чего-то еще?"
мы в небольшой компании по разработке небольших проектов для электронной коммерции и недвижимость.
Как я могу воспользоваться ООП в" повседневной, реальной " установке? Или ООП действительно предназначена для решения сложных проблем, а не для "повседневного" развития?
13 ответов
хорошие вещи об ООП происходят от привязки набора данных к набору поведений.
Итак, если вам нужно выполнить много связанных операций над связанным набором данных, вы можете написать много функций, которые работают со структурой, или вы можете использовать объект.
объекты дают вам некоторую помощь повторного использования кода в виде наследования.
IME, легче работать с объектом с известным набором атрибутов и методов, чтобы сохранить набор сложных структур и функции, которые на них работают.
некоторые люди будут продолжать о наследовании и полиморфизме. Они ценны, но реальная ценность ООП (на мой взгляд) исходит из того, как она инкапсулирует и связывает данные с поведением.
следует ли использовать ООП в своих проектах? Это зависит от того, насколько хорошо ваш язык поддерживает ООП. Это зависит от типов проблем, которые вам нужно решить.
но, если вы делаете небольшие веб-сайты, вы все еще говорите о достаточно сложно, чтобы я использовал дизайн ООП при правильной поддержке на языке разработки.
мой личный взгляд: контекст
когда вы программируете в ООП, у вас есть большее понимание контекста. Это поможет вам организовать код таким образом, чтобы его было легче понять, потому что реальный мир также объектно-ориентирован.
больше, чем получить что - то просто работать-точка вашего друга, хорошо разработанный дизайн OO легче понять, следовать, расширять, расширять и реализовывать. Например, намного проще делегировать работу, которая категорически похожа или хранить данные, которые должны оставаться вместе (да, даже структура C является объектом).
Ну, я уверен, что многие люди дадут гораздо более академически правильные ответы, но вот мой взгляд на некоторые из самых ценных преимуществ:
- ООП позволяет лучше инкапсуляции
- ООП позволяет программисту думать в более логических терминах, что делает программные проекты легче проектировать и понимать (если хорошо разработаны)
- ООП экономия времени. Например, посмотрите, что вы можете сделать с объектом строки C++, векторами и т. д. Все это функциональность (и многое другое) поставляется бесплатно."Теперь это действительно функции библиотек классов, а не сам ООП, но почти все реализации ООП поставляются с хорошими библиотеками классов. Можете ли вы реализовать все это на C (или большую его часть)? Конечно. Но зачем писать самому?
посмотрите на использование шаблонов проектирования, и вы увидите полезность ООП. Речь идет не только о инкапсуляции и повторном использовании, но и о расширяемости и ремонтопригодности. Это интерфейсы, которые делают вещи мощными.
несколько примеров:
реализация потока (шаблон декоратора) без объектов затруднена
добавление новой операции в существующую систему, такую как новый тип шифрования (шаблон стратегии), может быть затруднено без объектов.
посмотрите, как PostgresQL реализованы и ваш книга базы данных говорит, что база данных должна быть реализованы и вы увидите большой разница. Книга предложит объекты узлов для каждого оператора. И Postgres использует множество таблиц и макросы для эмуляции этих узлов. Это гораздо менее красиво и много из-за этого его труднее продлить.
список продолжается.
сила большинства языков программирования заключается в абстракциях, которые они делают доступными. Объектно-ориентированное программирование предоставляет очень мощную систему абстракций, позволяющую управлять отношениями между связанными идеями или действиями.
рассмотрим задачу вычисления площадей для произвольной и расширяющейся коллекции фигур. Любой программист может быстро написать функции для зоны круга, квадрата, треугольника, ект. и храните их в библиотеке. Этот сложность возникает при попытке написать программу, которая идентифицирует и вычисляет площадь произвольной формы. Каждый раз, когда вы добавляете новый вид формы, скажем, Пентагон, вам нужно будет обновить и расширить что-то вроде IF
или CASE
структура, чтобы ваша программа могла определить новую форму и вызвать правильную подпрограмму области из вашей "библиотеки функций". Через некоторое время расходы на техническое обслуживание, связанные с этим подходом, начинают накапливаться.
С объектно-ориентированным Программирование, многое из этого приходит бесплатно - просто определите класс формы, который содержит метод area. Тогда не имеет значения, с какой конкретной формой вы имеете дело во время выполнения, просто сделайте каждую геометрическую фигуру объектом, который наследуется от формы, и вызовите метод area. Объектно-ориентированная парадигма обрабатывает детали того, нужно ли в данный момент времени, с помощью этого пользовательского ввода, вычислять площадь круга, треугольника, квадрата, пятиугольника или эллипса, который только что был добавлен полминуты назад.
Что делать, если вы решили изменить интерфейс за тем, как была вызвана функция области? При объектно-ориентированном программировании вы просто обновите класс Shape и изменения автоматически распространятся на все сущности, наследующие этот класс. С не объектно-ориентированной системой вы столкнетесь с задачей пробиваться через вашу "библиотеку функций" и обновлять каждый отдельный интерфейс.
В общем, объектно-ориентированное программирование обеспечивает мощную форму абстракции, которая может сэкономить ваше время и усилия, устраняя повторение в коде и оптимизируя расширения и обслуживание.
все парадигмы программирования имеют одну и ту же цель: скрыть ненужную сложность.
некоторые проблемы легко решаются с помощью императивной парадигмы, как ваш друг использует. Другие проблемы легко решаются с помощью объектно-ориентированной парадигмы. Есть много других парадигм. Основные из них (логическое программирование, функциональное программирование и императивное Программирование) эквивалентны друг другу; объектно-ориентированное программирование обычно рассматривается как расширение императивное Программирование.
объектно-ориентированное программирование лучше всего использовать, когда программист моделирует элементы, похожие, но не одинаковые. Императивная парадигма поместила бы различные типы моделей в одну функцию. Объектно-ориентированная парадигма разделяет различные типы моделей на различные методы для связанных объектов.
ваш коллега, похоже, застрял в одной парадигме. Удача.
около 1994 года я пытался понять смысл ООП и C++ одновременно и обнаружил, что разочарован, хотя в принципе мог понять, какова ценность ООП. Я настолько привык к тому, что могу возиться с состоянием любой части приложения с других языков (в основном базовых, ассемблерных и языков семейства Паскаль), что казалось, что я отказываюсь от производительности в пользу какой-то академической абстракции. К сожалению, мои первые несколько встреч с OO-фреймворками, такими как MFC, это легче взломать, но не обязательно дает много на пути к просветлению.
только благодаря сочетанию настойчивости, воздействию альтернативных (не-c++) способов работы с объектами и тщательному анализу кода OO, который 1) работал и 2) читал более связно и интуитивно, чем эквивалентный процедурный код, я начал действительно его получать. И 15 лет спустя я регулярно удивляюсь новым (для меня) открытиям умных, но впечатляюще простых решений OO я не могу себе представить, чтобы это было так аккуратно в процедурном подходе.
Я проходил через тот же набор борьбы, пытаясь понять парадигму функционального программирования в течение последних нескольких лет. Перефразируя Пола Грэма, когда вы смотрите вниз на энергетический континуум, вы видите все, чего не хватает. Когда вы смотрите на энергетический континуум, вы не видите силу, вы просто видите странность.
Я думаю, чтобы совершить что-то другое вы должны 1) увидеть, что кто-то явно более продуктивен с более мощными конструкциями и 2) приостановить недоверие, когда вы обнаружите, что ударяетесь о стену. Вероятно, полезно иметь наставника, который, по крайней мере, немного продвинулся в понимании новой парадигмы.
за исключением смекалки, необходимой для приостановки недоверия, если вы хотите, чтобы кто-то быстро оценил ценность модели OO, я думаю, вы могли бы сделать намного хуже, чем попросить кого-то провести неделю с Прагматичные программисты книга на рельсах. К сожалению, он не учитывает многие детали того, как работает магия, но это довольно хорошее введение в силу системы абстракций OO. Если после работы над этой книгой ваш коллега по какой-то причине все еще не видит ценности ОО, он/она может оказаться безнадежным случаем. Но если они готовы потратить немного времени на работу с подходом, который имеет сильно самоуверенный дизайн OO, который работает, и получает их от 0-60 намного быстрее, чем делая то же самое на процедурном языке, можно просто надеяться. Я думаю, что это правда, даже если ваша работа не связана с веб-разработкой.
Я не уверен, что создание "реального мира" будет такой же точкой продажи, как рабочая структура для написания хороших приложений, потому что оказывается, что, особенно в статически типизированных языках, таких как C# и Java, моделирование реального мира часто требует извилистых абстракций. Вы можете увидеть конкретный пример сложности моделирования реальный мир, глядя на тысячи людей, изо всех сил пытающихся смоделировать что-то такое якобы простое, как геометрическая абстракция "формы" (Форма, эллипс, круг).
для меня сила ООП не проявляется, пока вы не начнете говорить о наследовании и полиморфизме.
Если аргумент для ООП основывается на концепции инкапсуляции и абстракции, ну, это не очень убедительный аргумент для меня. Я могу написать огромную библиотеку и только документировать интерфейсы к ней, о которых я хочу, чтобы пользователь знал, или я могу полагаться на языковые конструкции, такие как пакеты в Ada, чтобы сделать поля закрытыми и только раскрывать то, что я хочу разоблачать.
однако реальное преимущество приходит, когда я написал код в общей иерархии, чтобы его можно было использовать позже, так что те же самые точные интерфейсы кода используются для разных функций для достижения того же результата.
Почему это удобно? Потому что я могу стоять на плечах гигантов, чтобы выполнить свою задачу. Идея в том, что я могу свести части проблемы к самым основным частям, объектам, которые составляют объекты, которые составляют... этот объекты, составляющие проект. Используя класс, который очень хорошо определяет поведение в общем случае, я могу использовать тот же проверенный код для создания более конкретной версии того же самого, а затем более конкретной версии того же самого, а затем еще более конкретной версии того же самого. Ключ в том, что каждая из этих сущностей имеет общность, которая уже была закодирована и протестирована, и нет необходимости повторно ее воспроизводить позже. Если я не использую наследство для этого, я в конечном итоге переопределение общей функциональности или явное связывание моего нового кода со старым кодом, что обеспечивает сценарий для меня, чтобы ввести ошибки потока управления.
полиморфизм очень удобен в случаях, когда мне нужно достичь определенной функциональности от объекта, но такая же функциональность также необходима от аналогичных, но уникальных типов. Например, в Qt есть идея вставки элементов в модель, чтобы можно было отображать данные и легко поддерживать метаданные для этого объекта. Без полиморфизма мне нужно было бы беспокоиться о гораздо более подробной информации, чем в настоящее время (т. е. мне нужно было бы реализовать те же интерфейсы кода, которые проводят ту же бизнес-логику, что и элемент, который изначально предназначался для модели). Поскольку базовый класс моего объекта с привязкой к данным взаимодействует с моделью, я могу без проблем вставлять метаданные в эту модель. Я получаю то, что мне нужно от объекта, не заботясь о том, что нужно модели, и модель получает то, что ей нужно, не заботясь о том, что я добавил в класс.
попросите своего друга визуализировать любой объект в его комнате, доме или городе... и если он может сказать хоть один такой объект, какая система сама по себе и способна выполнять какую-то осмысленную работу.
такие вещи, как кнопка не делает что - то в одиночку-требуется много объектов, чтобы сделать телефонный звонок.
аналогично двигатель автомобиля выполнен из коленчатого вала, поршней, свечей зажигания. Концепции OOPS развились из нашего восприятия в естественных процессах или вещах в нашей жизни.
книга "Inside COM" рассказывает о цели COM, беря аналогию из детской игры идентификации животных, задавая вопросы.
дизайн превосходит технологию и методологию. Хорошие проекты, как правило, включают универсальные принципы управления сложностью, такие как закон Деметры, который лежит в основе того, что языковые функции OO стремятся кодифицировать.
хороший дизайн не зависит от использования OO конкретных языковых функций, хотя, как правило, в интересах их использования.
не только это делает
- программирование проще / более ремонтопригодно в текущей ситуации для других людей (и себя)
- это уже позволяет легче базы данных CRUD (создание, обновление, удаление) операций.
вы можете найти больше информации об этом, глядя вверх: - Java: Спящий Режим - Dot Net: Entity Framework
смотрите даже, как LINQ (Visual Studio) может сделать вашу жизнь программирования намного проще.
- также, вы можете начать использовать шаблоны проектирования для решения реальных жизненных проблем (шаблоны проектирования-это все ОО)
возможно, это даже интересно продемонстрировать с небольшой демонстрацией:
- предположим, вам нужно хранить сотрудников, учетные записи, членов, книги в текстовом файле аналогичным образом.
.PS. Я попытался написать его псевдо-способом:)
ОО так
код вызов: Ио.файл.сохранить (objectsCollection.ourFunctionForSaving ())
класс objectsCollection
функция ourFunctionForSaving () как String
String _Objects
for each _Object in objectsCollection
Objects &= _Object & "-"
end for
return _Objects метод end
NON-OO Way
Я не думаю, что запишу не-oo код. Но подумайте об этом:)
ТЕПЕРЬ СКАЖЕМ
в пути ОО. Вышеуказанный класс является родительским классом всех методов сохранения книг, сотрудники, члены, счета, ... Что произойдет, если мы хотим изменить путь сохранения в текстовый файл? Например, чтобы сделать его компактным с текущим стандартом (.РЕЗЮМЕ.)
и предположим, что мы хотели бы добавить функцию загрузки, сколько кода вам нужно написать? В OO-way вам нужен только метод add a New Sub, который может разделить все данные на параметры (это происходит один раз).
пусть ваш коллега подумает об этом:)
в областях, где состояние и поведение плохо выровнены, объектная ориентация уменьшает общую плотность зависимостей (т. е. сложность) в этих областях, что делает результирующие системы менее хрупкими.
Это так суть объектная ориентация основана на том, что организационно она вообще не различает состояние и поведение, рассматривая оба одинаково как "особенности". Объекты-это просто наборы функций clumpled свести к минимуму в целом зависимость.
в других областях объектная ориентация-не лучший подход. Существуют различные языковые парадигмы для различных проблем. Опытные разработчики знают это и готовы использовать любой язык, наиболее близкий к домену.