ООП становится легче или сложнее? [закрыто]

36

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

Stock stock = new Stock();
stock.addItem(item);
stock.removeItem(item);

Это было легче понять с помощью информативного имени.

Но теперь ООП с такими шаблонами, как объекты передачи данных, объекты значений, репозиторий, внедрение зависимостей и т. Д., Стало более сложным. Для достижения вышеизложенного вам может потребоваться создать несколько классов (например, abstract, factory, DAO и т. Д.) И реализовать несколько интерфейсов.

Примечание: я не против лучших практик, которые облегчают совместную работу, тестирование и интеграцию

Tunmise Fasipe
источник
23
Создать хорошую программную архитектуру всегда было сложно и, скорее всего, всегда будет.
Йоханнес
6
Я бы переименовал addItemдля addи removeItemдля remove. Потому что это легче читать. stock.add(item)или stock.remove(item). И больше ООП ориентированных.
Разпейтия
1
Оригинальный ООП почти не выглядел как то, что вы показали. ООП не о синтаксисе , а о некой абстракции, популяризированной Smalltalk. Это не обязательно доказывает, что вы не правы, и не является ошибочной предпосылкой; скорее это даже более верно, чем вы думаете.
Конрад Рудольф
1
по вашей логике вы сравниваете яблоки и апельсин, тогда императивное программирование (т.е. циклы и условие if) проще, чем все, что мы имеем сегодня. Императивное программирование - это строительные блоки для классов / ООП, а классы / ООП - это строительные блоки для шаблонов проектирования. Вещи становятся более сложными по мере вашего прогресса, потому что вы решаете более сложные проблемы.
Ли Райан
2
@LieRyan - Я видел, что проблемы становятся сложными только потому, что никто из ответственных не смог решить их с помощью простого императивного программирования и атаковал их с помощью шаблонов проектирования поверх ООП поверх простого императивного решения, которое должно было быть реализовано в одиночку.
Mouviciel

Ответы:

35

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

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

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

Другая причина может заключаться в том, что хотя парадигма сложности не изменилась, размер и сложность среднего программного проекта вполне могут измениться. С вычислительной мощностью, доступной на мобильных телефонах потребительского уровня, которые были бы мечтой разработчика на сервере менее двух десятилетий назад, широкая публика в основном ожидала гладкого анимированного графического интерфейса даже для самого дешевого одноразового приложения, а настольный ПК начального уровня стал более мощным чем «суперкомпьютер» 1980-х годов, вполне естественно, что планка была поднята с первых дней Smalltalk и C ++.

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

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

tdammers
источник
Таким образом, шаблоны проектирования добавили сложности. Значения шаблонов проектирования не обязательно являются ООП, но добавляются для улучшения ООП.
Tunmise Fasipe
@tunmisefasipe: не совсем. Шаблоны проектирования - это просто проверенные решения стандартных проблем; они не «дополнение» к ООП, а следствие. Сложность уже была там; шаблоны проектирования просто обеспечивают стратегии поваренной книги, чтобы заняться этим.
tdammers
17

Нет, это становится все более изощренным. И вы правы - в чате SO C ++ мы часто шутим о AbstractSingletonFactoryProxyBeanBridgeAdapterManagers, которые мы видим в коде Java.

Но хороший код не обладает этим свойством. В хорошем коде вы все еще можете сказать

std::stack<int> s;
s.push(5);
s.pop();
DeadMG
источник
4
Непонятно из вашего поста, но я думаю, что чрезмерное проектирование очевидно в коде Java и C ++. Само по себе это не свойство ни одного языка, а практика программистов ... Оба языка позволяют писать хороший код, хотя ни один (IMO) для него не подходит :) Фреймворки в Java, к сожалению, плохи.
Андрес Ф.
12
Говоря о чрезмерном проектировании, этот поток является обязательным: обсуждения.joelonsoftware.com/default.asp?joel.3.219431
Безопасный
3
@AndresF. правда, но вы, кажется, не получаете столько в коде C ++, а в Java и .NET: просто посмотрите на шаблон проектирования MVVMVMMD msdn.microsoft.com/en-us/magazine/hh965661.aspx как один пример того, как вы берете «простой код» и добавляете к нему шаблон дизайна, чтобы он выглядел «проще», а затем добавляете другой шаблон дизайна к шаблону дизайна, потому что исходный шаблон был не так прост, как рекламируется. Избыточное проектирование становится все более и более распространенным явлением.
gbjbaanb
5
Я бы поспорил с «становлением» немного. Избыточное проектирование так же стара, как и инженерное.
Gort Робот
4
@AndresF. Мы особенно против Java в чате, но это правда, что Java, в большей степени, чем C ++ , поощряет чрезмерное проектирование, потому что это делает его более доступным (GC), и популярные корпоративные библиотеки Java популяризировали этот стиль, как вы заметили сами.
Конрад Рудольф
10

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

Много лет назад я работал над системой, в которой класс домена отвечал за загрузку себя из базы данных, например

var userId = Request.QueryString["UserID"].ToInt();
var user = new User(userId);
user.Name = ...;
...
user.Save();

Это очень понятный код. Нет проблем в понимании этого. Однако проблема заключается в модульном тестировании кода. А именно, как бы я протестировал Userкласс без необходимости загружать его из базы данных? И как бы я протестировал этот код обработки веб-запросов, не имея доступа к базе данных? Это просто невозможно.

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

Итак, если мы вернемся к примеру, который вы пишете, что бы вы сделали с акцией после ее создания? Сохраните это в базе данных

Stock stock = new Stock();
stock.addItem(item);
stock.removeItem(item);
this.StockRepository.Add(stock);

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

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

Пит
источник
Вы знаете, какое усилие вы должны приложить для настройки своего хранилища. Хотя после настройки он стал многоразовым.
Tunmise fasipe
возможно, проблема в модульном тестировании, если бы у нас были лучшие инструменты для тестирования всего (как и вам в любом случае) вместо крошечных кусочков, у нас были бы системы, в которых было бы меньше ошибок?
gbjbaanb
2
@gbjbaanb: у нас это уже есть, это называется интеграционным / функциональным тестированием. Модульное тестирование служит другой, но одинаково необходимой цели
Кевин
@gbjbaanb - У нас уже есть отличные инструменты для общесистемного / приемочного тестирования, например, Cucumber на платформе Rails. Но команды, которые действительно хороши и пишут очень мало ошибок, но также быстро справляются, они пишут множество юнит-тестов и всего несколько системных тестов. Смотрите о « Тестовом
Пит
4

Ни. Наши проблемы на самом деле не изменились; планка для приемлемого кода была поднята.

Для достижения вышеизложенного вам может потребоваться создать несколько классов (например, abstract, factory, DAO и т. Д.) И реализовать несколько интерфейсов.

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

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

Telastyn
источник
3

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

Жанна Боярская
источник
Также обратите внимание, что фреймворки накапливаются со временем. Так что да, программирование требует больше знаний. Это также означает, что можно сделать больше за меньшее время.
Жанна Боярская
3

Языки программирования, использующие ОО сегодня, пытаются удовлетворить сложные требования и среды, которые постоянно меняются. ОО позволяет своим пользователям скрывать различные уровни сложности (среди прочих функций), чтобы кодирование стало более понятным и более легким для построения и понимания. Тем не менее, эта функция не всегда из коробки. В вашем примере ОО позволил вам скрыть некоторые детали от меня, предоставив метод для управления элементами в коллекции и, возможно, даже для сохранения его с помощью метода «AddItem». Трата усилий на сокрытие сложности может привести к простой в использовании и многократно используемой среде, которая упрощает жизнь. Например, многие реализации ORM позволяют вам взаимодействовать с базами данных без того, чтобы программист записывал детали SQL. Это действительно мощно и делает его проще для разработчика.

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

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

Без шансов
источник
Ясные моменты. Я знаю ЯГНИ. Что такое поцелуй?
Tunmise fasipe
2
@tunmisefasipe, KISS - это краткое название принципа дизайна. Оригинальные слова: «Не усложняйте (глупо)» (ref: en.wikipedia.org/wiki/KISS_principle ), но более вежливое выражение может быть «Не усложняйте».
NoChance
3
@tunmisefasipe - KISS = Сохраняй это простым, глупый. Фраза, которую я повторяю себе «OVER», «OVER» и «OVER», и кажется, что она до сих пор не всегда звучит.
Michael Kohne
@MichaelKohne, мы все делаем! Я думаю, что это искусство, чтобы быть в состоянии упростить вещи. E = M C C говорит очень много в очень сжатой форме!
NoChance
3

Краткий ответ : Да, потому что вы имеете дело с более сложными проблемами.

Длинный ответ (сильно предвзятый) : Для меня шаблоны проектирования обычно указывают на то, что у некоторой парадигмы есть проблемы в данной области. Шаблоны ООП имеют дело с проблемами ООП (на более низком уровне шаблоны Java имеют дело с проблемами Java), шаблоны FP имеют дело с проблемами FP и т. Д.

Во время программирования у вас могут быть разные приоритеты. Возможно, вы захотите иметь правильную программу, вам может потребоваться сократить время выхода на рынок, максимально быструю программу, долгосрочную ремонтопригодность или мгновенную ремонтопригодность при новом найме. В зависимости от пушистости вы будете сильно отличаться - если вы программируете контроллер электростанции, вы хотите сделать это правильно с первого раза, а не исправлять ошибки каждый раз время от времени («происходит ли сбой каждый раз, когда вы нажимаете Ctrl+Alt+Del?»). Если вы находитесь в HPC, логика может быть относительно простой, но вы хотите выполнить ее как можно быстрее и т. Д. И т. Д. Кроме того, некоторые парадигмы лучше подходят для определенных задач (например, AI и логическое программирование, базы данных и реляционные базы данных).

ООП в некоторой степени «слишком хорош» в простых случаях, и это «моделирование реальной жизни». Например , в первой книге о ООП я прочитал там были классы Person, Employeeи Managerс is-aотношением. Пока все хорошо, но что, если сотрудник повысится до менеджера?

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

PS. Да - ответ предвзят в отношении ООП, и я признаю, что в некоторой степени он «реагирует» на ООП. У ООП есть свои применения, но, на мой взгляд, это не единственное, окончательное решение.

PPS. Да - используйте шаблоны проектирования - они в конечном итоге упрощают программирование ООП.

PPPS. Я использовал ООП как синоним императивного программирования ООП.

Мацей Печотка
источник
2

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

Ранние ООП книги (особенно ранние книги по Java) представляли собой абсурдно упрощенное представление о разработке приложений. Примеры «Дебет банковского счета с помощью 10-строчной Java-программы» всегда были особенно раздражающими, так как я видел примеры из реальной жизни этой простой задачи, выполняющей до 6000 строк кода COBOL (и попытка замены Java, выполнявшейся до 3500 строк, прежде чем она была отменена как невыполнимо!).

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

Но если вы хотите увидеть, как управлять банковским счетом всего за 15 строк кода, функциональное программирование - ваш человек

Джеймс Андерсон
источник