Разве MVC не против ООП?

62

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

В шаблоне Model-View-Controller данные и логика / алгоритмы размещаются в разных объектах, модели и контроллере соответственно. При эквивалентном подходе ООП модель и контроллер не должны находиться в одном и том же логическом объекте?

m3th0dman
источник
11
Почему они должны быть в одной и той же логической сущности? Вы не указали, почему это будет выгодно, или почему ООП будет диктовать эту договоренность.
Роберт Харви
26
Ну, бизнес-логика идет в модели, а не в контроллере. Контроллер действительно просто посредник, склеивающий вид и модель. Таким образом, в модели у вас есть данные и поведение в одном месте.
Роберт Харви
2
Какая? Объединение данных и поведения вместе - вот что такое ООП.
Энди
3
ООП - это разделение реализаций от интерфейсов. Интерфейсы больше связаны с поведением, а реализации больше с данными (именно поэтому данные имеют тенденцию быть скрытыми). Так что ООП - это не объединение данных и поведения, а их разделение.
Каз
5
В любом случае, вы не хотите объединять все данные и поведение в один класс. ООП-программы используют более одного класса для создания каркасов объектов. И вообще, если что-то «анти-ООП», это может быть хорошо. ООП - это не конец всему. ООП прямо-таки отстой. Пришло время преодолеть ООП.
Каз

Ответы:

45

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

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

В MVC бизнес-логика идет в модели, а не в контроллере. Контроллер действительно просто посредник, склеивающий вид и модель. Таким образом, в модели вы можете хранить данные и поведение в одном месте.

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


Я приведу вам конкретный пример. Это немного надумано, но, допустим, у вас есть Currencyобъект, и этот объект может представлять себя в любой доступной валюте, привязанной к доллару. Таким образом, у вас есть такие методы, как:

public decimal Yen { get { return // dollars to yen; } }
public decimal Sterling { get { return // dollars to sterling; } }
public decimal Euro { get { return // dollars to euro; } }

... и это поведение будет инкапсулировано с объектом Currency.

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

Таким образом, это поведение будет инкапсулировано в Tellerобъект, и оно будет принимать Currencyи Accountобъекты в качестве входных данных, но оно не будет содержать никаких данных, кроме, возможно, небольшого локального состояния (или, возможно, Transactionобъекта), чтобы помочь обработать входные объекты.

Роберт Харви
источник
И в каком объекте / пакете должен Tellerбыть помещен? В Controllerоткуда Teller'sметоды вызываются или в Modelпотому , что это часть бизнес - логики?
m3th0dman
Tellerидет в Model, хотя это может быть вызвано с контроллера. Это часть бизнес-сферы.
Роберт Харви
Я всегда думал, что использование модели для бизнес-правил делает MVC полуэффективным шаблоном. Использование модели для адаптеров к реальному приложению и наличие посредников между адаптерами и представлением всегда намного эффективнее в достижении SoC.
Ям Маркович
@YamMarcovic: Я не уверен, что вы имеете в виду. Модель является своего рода универсальным средством; на практике бизнес-правила обычно размещаются на собственном уровне обслуживания, но он все еще считается частью модели (например, вы не будете кодировать конкретные бизнес-правила в отдельном методе контроллера). Вы правы, что контроллеры являются посредником.
Роберт Харви
5
Я думаю, что большинство людей ошибаются в MVC, просто читая о нем, - это слишком широкие предположения о том, что означает «бизнес-логика». Если вы не можете открыть свою модель и использовать ее с минимальными изменениями или без изменений в новом приложении, которое будет иметь те же бизнес-цели, но совершенно другую архитектуру через контроллер с совершенно другой логикой приложения, вы делаете это неправильно ИМО. Конечно, все еще есть смысл отделять представления от любого сочетания всего, что у вас есть, но C, как легкая конструкция, кажется мне упускающим ключевую точку разделения.
Эрик Реппен
73

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

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

Майкл Боргвардт
источник
Объектно-ориентированный подход может масштабироваться на уровне абстракции; посмотрите, например, причину доменного дизайна, появившегося потому, что классическая многоуровневая архитектура не OOPish, а скорее процедурная. Это происходит на более высоком уровне абстракции, чем MVC.
m3th0dman
6
@ m3th0dman: Вы говорите в широком, широком смысле. Как насчет обсуждения специфики, например, как MVC устраняет кошмар спагетти-кода, который представляет собой Winforms или Webforms?
Роберт Харви
3
@ m3th0dman: это довольно упрощенная характеристика DDD.
Майкл Боргвардт
1
@RobertHarvey Чтобы быть уверенным, что вы противостоите тому, почему MVC хорош, потому что он избавляется от спагетти, на самом деле здесь нет конкурентов. Я согласен, но я склонен видеть, что MVC также реализован в процедурном порядке. Поэтому я думаю, что это уместный вопрос, а точнее - может быть, вопрос, который нужно задать: «Как часто люди внедряют MVC процедурно?»
Джимми Хоффа
1
@ Роберт Харви Цель вопроса не в том, насколько хорош или плох MVC; Речь идет о том, что основано или нет на принципах ОО.
m3th0dman
71

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

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

dasblinkenlight
источник
5
+1: мне обычно не нравятся объяснения через аналогии, но этот блестящий.
Майкл Боргвардт
@Caleb Это отличный момент, большое спасибо!
dasblinkenlight
19

ООП также касается разделения интересов , то есть разделения разных ролей / ответственности в разных объектах.

MVC разделяется на следующие компоненты:

  • Модель: данные и их бизнес-логика
  • Вид: представление данных
  • Контроллер: координация между моделью и видом.

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

марко-fiset
источник
Это правда, что принцип единой ответственности полезен для эффективного использования ООП, но я думаю, что не стоит утверждать, что «ООП также относится к принципу единой ответственности». Это кажется отсталым.
Калеб
@ Калеб Да, я понимаю, что ты имеешь в виду. Может быть, это можно перефразировать, но вы поняли.
Марко-Фисет
18

В шаблоне Model-View-Controller данные и логика / алгоритмы размещаются в разных объектах, модели и контроллере соответственно.

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

Подумайте об этом следующим образом: если объекты не могут передавать данные назад и вперед без нарушения инкапсуляции, у вас действительно может быть только один объект!

При эквивалентном подходе ООП модель и контроллер не должны находиться в одном и том же логическом объекте?

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

Калеб
источник
Я надеюсь, что у контроллера есть логика, но мало или нет состояния. Как вы думаете, в каком состоянии находится контроллер?
Мэтью Флинн
1
@MatthewFlynn Для начала, контроллер должен знать о представлении и модели. Кроме того, это может зависеть от того, о каком конкретном виде MVC мы говорим, но в целом контроллер может сохранять состояние, связанное с тем, как информация должна отображаться (например, текущий выбор), тогда как модель имеет дело с тем, какая информация отображается.
Калеб
1
@MattFenwick Вот что я имею в виду под «ароматом» ... Именно то, что вы храните в контроллере, а что в модели, является вопросом вкуса и соглашения. В Cocoa / Cocoa Touch обычно хранят такие элементы, как текущий выбор и даже пользовательские настройки в контроллере. MVC, используемый в некоторых веб-фреймворках, может поместить почти все в модель и очень мало в контроллер. YMMV.
Калеб
4
@MatthewFlynn Большинство согласится с вами, но ИМО, люди воспринимают бизнес-логику как более широкую категорию, чем она должна быть. Контроллер обрабатывает логику приложения, которую люди часто путают с бизнес-логикой. В идеальном разделении интересов я должен иметь возможность повторно использовать объект модели в совершенно другой архитектуре приложения, служащей тем же бизнес-целям, без изменения бизнес-объекта. Все, что нужно новому приложению, - это использовать интерфейс и выполнять свои собственные операции с данными и транзакциями, когда они возвращаются и обрабатываются.
Эрик Реппен
1
@MattFenwick: рассмотрим многопользовательское приложение. Существует очевидная точка, в которой можно провести черту между моделью и контроллером, это то, что модель обрабатывает общее состояние и контролирует локальное состояние. Текущий выбор является локальным, поэтому он идет в контроллере.
Ян Худек
4

MVC - это шаблон, который описывает разумный способ взаимодействия объектов; это не сам метакласс. При этом ОО описывает описания поведения и данных сущностей и то, как эти сущности взаимодействуют. Это не объединение всей системы в один массивный объект.

Джонатан Уэтерхед
источник
2

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

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

superM
источник
2

Уровень модели - это не просто данные, а уровень контроллера - просто логика.

Уровень контроллера будет иметь полную коллекцию объектов для своих целей. Будут объекты для получения входных данных из представления и от преобразования этих входных данных в форму, которую может обработать модель. Фреймворк Struts Java имеет хороший пример этого в своей модели Action / Form. Форма заполняется вводом от пользователя, а затем передается в действие. Действие берет эти данные и использует их для манипулирования моделью.

Точно так же слой Model не полностью состоит из данных. Возьмите, например, объект «Пользователь» - вам может понадобиться код, который получает пользователя из базы данных, или код, чтобы связать пользователя с заказом, или для проверки того, что адрес пользователя находится в области обслуживания вашей компании ... вы получаете рисунок. Это не логика контроллера. Это бизнес-логика, и это привело к тому, что многие разделили свой уровень модели на несколько уровней, таких как уровни Service или Manager для бизнес-логики, уровень DAO (объект доступа к базе данных) для доступа к базе данных и другие.

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

Майкл К
источник
2

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

В MVC функциональность для отображения части данных (представление) хранится отдельно от данных (модель). Почему это? Именно так можно изменить логику отображения без необходимости изменения базовых данных. Это позволяет легко менять представление, когда вам нужно по-разному представлять одни и те же данные: или когда меняются характеристики оборудования дисплея: или когда вы переключаетесь с Windows на Linux; или когда вы хотите, чтобы два человека имели два разных взгляда на одни и те же данные.

MVC не конфликтует с ООП - на самом деле он основан на правильном применении объектно-ориентированных принципов.

DJClayworth
источник
0

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

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

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

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

Эрик Реппен
источник
0

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

Например, весь смысл OOP / OOD состоит в том, чтобы сделать ваш код более модульным и многократно используемым. Да?

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

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

DJM
источник
Я бы сказал, что MVC и компонентно-ориентированная архитектура - это шаблоны проектирования, не выходящие за рамки подходов ООП, в то время как ООД / ООП - это просто путаница и столкновение школ мысли и маладемии о том, как использовать граничащее вездесущее программирование. построить правильно. Сравнение двух категорий вещей похоже на сравнение квадратов и ручки, которую вы использовали для рисования квадратов.
Эрик Реппен
-1

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

Итак, я думаю, что реальный вопрос таков; мы более склонны к процедурному коду при использовании шаблона MVC.

(а может, я просто получу несколько голосов вниз?)

aserwin
источник
-1

Не анти, но и ООП не требуется для MVC.

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

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

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

luke1985
источник
Ха-ха, я вижу, что некоторые люди страдают от а **, когда сталкиваются с фактами. Слишком много усилий делать собственные фреймворки с ООП? Не могу терпеть потерянное время? Самые простые ответы - лучшие.
luke1985
Не уверен, почему этот ответ имеет отрицательные голоса. Он говорит, что они не связаны, и не "анти". Кажется довольно точным.
mwilcox
-3

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

user123790
источник
это только ваше мнение или вы можете как-то это подтвердить?
комнат