Чи не MVC anti OOP?


61

Основна ідея OOP полягає в об'єднанні даних і поведінки в єдине ціле - об'єкт. У процедурному програмуванні є дані та окремо алгоритми, що модифікують дані.

У шаблоні Model-View-Controller дані та логіка / алгоритми розміщуються у різних об'єктах відповідно моделі та контролері. Чи в еквівалентному підході OOP не повинні модель та контролер розміщуватися в одній логічній сутності?


11
Чому вони повинні бути в одній логічній сутності? Ви не заявляли, чому це було б вигідно, або чому OOP диктуватиме цю домовленість.
Роберт Харві

26
Ну, бізнес-логіка йде в моделі, а не в контролері. Контролер насправді є лише проміжним з’єднанням, щоб склеїти Погляд та Модель. Тож у моделі ви маєте дані та поведінку в одному місці.
Роберт Харві

2
Що? Об’єднання даних та поведінки разом - саме те, про що йдеться.
Енді

3
OOP - це про відділення реалізацій від інтерфейсів. Інтерфейси більше пов'язані з поведінкою, а реалізація - більше з даними (саме тому дані, як правило, приховуються). Таким чином, OOP полягає не в об'єднанні даних і поведінки, а в їх розділенні.
Каз

5
У будь-якому випадку, ви не хочете згрупувати всі дані та поведінку в один клас. Програми OOP використовують більше одного класу для створення каркасів об'єктів. І все одно, якщо щось є "анти-ООП", це може бути хорошою справою. OOP - це не все кінця. OOP прямо смокче. Настав час подолати OOP.
Каз

Відповіді:


44

MVC - вправа розділення проблем , архітектури інтерфейсу. Це спосіб вирішити складність, яка може виникнути в інтерфейсах користувача через те, що презентація не відділяється від контенту .

Теоретично всі об'єкти можуть мати поведінку, яка діє на даних, які вони містять, і дані та поведінка залишаються в капсулі . На практиці даний об'єкт OOP може мати або не мати логіку, яка відповідає його даним, або взагалі не мати будь-якої логіки ( наприклад, Об'єкт передачі даних ).

У MVC бізнес-логіка йде в моделі, а не в контролері. Контролер насправді є лише проміжним з’єднанням, щоб склеїти Погляд та Модель. Тож у моделі ви можете мати дані та поведінку в одному місці.

Але навіть така домовленість не гарантує суворого злиття даних / поведінки. Об'єктами, що містять лише дані, можна керувати іншими класами, що містять лише логіку, і це цілком прийнятне використання OOP.


Наведу конкретний приклад. Це трохи надумано, але скажімо, у вас є 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; } }

... і ця поведінка буде інкапсульована об'єктом валюти.

Але що робити, якщо я хотів перевести валюту з одного рахунку на інший або депозитувати якусь валюту? Чи така поведінка також буде інкапсульована в об'єкт Валюта? Ні, не буде. Гроші у вашому гаманці не можуть перераховуватися з гаманця на ваш банківський рахунок; вам потрібен один чи більше агентів (касир чи банкомат), щоб допомогти отримати гроші на ваш рахунок.

Таким чином, така поведінка буде інкапсульована в Tellerоб'єкт, і вона буде приймати Currencyі Accountоб'єкти як вхідні дані, але вона не міститиме жодних даних, за винятком, можливо, трохи місцевого стану (або, можливо, Transactionоб'єкта), який допоможе обробити вхідні об'єкти.


І в яку сутність / пакет слід Tellerрозміщувати? У тому, Controllerзвідки Teller'sметоди називаються, або Modelтому, що це частина ділової логіки?
m3th0dman

Tellerйде в Model, хоча це може бути викликано від контролера. Це частина домену бізнесу.
Роберт Харві

Я завжди думав, що використання Моделі для бізнес-правил робить MVC напівефективною схемою. Використання Моделі для адаптерів до реального застосування та забезпечення посередництва контролерів між адаптерами та видом завжди набагато ефективніше для досягнення SoC.
Ям Маркович

@YamMarcovic: Я не впевнений, що ти маєш на увазі. Модель є своєрідною заганкою; на практиці правила бізнесу зазвичай розміщуються у власному рівні обслуговування, але він все ще вважається частиною Моделі (наприклад, ви б не кодували конкретні бізнес-правила в рамках окремого методу контролера). Ви праві, що контролери є посередником.
Роберт Харві

4
Одне, я думаю, що більшість людей помиляються про MVC лише від того, щоб прочитати його, - це занадто широкі припущення про те, що означає "бізнес-логіка". Якщо ви не можете випустити свою модель і використовувати її з мінімальними або без будь-яких модифікацій у абсолютно новому додатку, який матиме ті ж бізнес-цілі, але зовсім іншу архітектуру через контролер із зовсім іншою логікою програми, ви робите це неправильно ІМО. Досі є значення в роз'єднанні поглядів від будь-якої суміші всього іншого, що у вас є, звичайно, але С як легка конструкція вражає мене як відсутність ключової точки розлуки.
Ерік Реппен

73

MVC працює на набагато більшому рівні абстракції, ніж поодинокі об'єкти, і насправді кожен із трьох (модель, перегляд та контролер), як правило, складається з багатьох об'єктів, кожен з яких має як дані, так і поведінку.

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


Об'єктно-орієнтований підхід може масштабуватися за рівнем абстракції; див., наприклад, причину дизайну, керованого доменом, який з'явився тому, що класична шарувата архітектура не є OOPish, а скоріше процедурною. Це відбувається при більш високому рівні абстракції, ніж MVC.
m3th0dman

6
@ m3th0dman: Ви говорите в широких, широких загалах. Як щодо обговорення специфіки, наприклад, як MVC усуває кошмар коду спагетті, який є Winforms або Webforms?
Роберт Харві

3
@ m3th0dman: це досить спрощена характеристика DDD.
Майкл Боргвардт

1
@RobertHarvey Щоб бути впевненим, що ти протилежний тому, чому MVC хороший тим, що він усуває спагетті, насправді тут не змагається. Я погоджуюся, але я схильний бачити, що MVC реалізується і в процедурній схемі. Тому я думаю, що це відповідне питання, а точніше - можливо, питання, яке потрібно задати, - "Як часто люди реалізують MVC процедурно?"
Джиммі Хоффа

1
@ Роберт Харві Мета питання не в тому, наскільки хороший чи поганий MVC; йдеться про те, що ґрунтується на принципах ОО чи ні.
m3th0dman

71

OOP не обмежує взаємодію між об'єктами, у яких кожен має свої дані та власну поведінку.

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


5
+1: Я зазвичай не люблю пояснень через аналогії, але це геніальне.
Майкл Боргвардт

@Caleb Це чудовий момент, дуже дякую!
dasblinkenlight

19

OOP також стосується розділення проблем , тобто для розділення різних ролей / відповідальності в різних об'єктах.

MVC розділяється на наступні компоненти:

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

Таким чином, ці обов'язки чітко розрізнені і їх дійсно слід розділити на кілька об'єктів.


Це правда, що принцип єдиної відповідальності є корисним для ефективного використання ООП, але я вважаю, що слід сказати, що "ООП - це також принцип єдиної відповідальності". Це здається відсталим.
Калеб

@Caleb Так, я розумію, що ти маєш на увазі. Можливо, це може бути перефразоване, але ви розумієте.
marco-fiset

18

У шаблоні Model-View-Controller дані та логіка / алгоритми розміщуються у різних об'єктах відповідно моделі та контролері.

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

Подумайте про це так: якщо об’єкти не зможуть передавати дані туди-сюди, не порушуючи інкапсуляцію, у вас дійсно може бути лише один об’єкт!

Чи в еквівалентному підході OOP не повинні модель та контролер розміщуватися в одній логічній сутності?

MVC - це підхід OOP - конкретно, це рецепт рішення про те, як використовувати об'єкти для ефективної організації програми. І ні , модель і контролер не повинні бути однією сутністю. Контролер дозволяє розділяти між моделлю та видом. Збереження моделі та перегляду незалежно одне від одного робить їх і більш випробуваними, і більш корисними для використання.


Я би сподівався, що у контролера є логіка, але мало в чому стану. Який ти стан, на вашу думку, має контролер?
Меттью Флінн

1
@MatthewFlynn Для початку контролеру необхідно знати про вигляд та модель. Крім того, це може залежати від конкретного аромату MVC, про який ми говоримо, але загалом контролер може зберігати стан, пов’язаний із тим, як повинна відображатися інформація (наприклад, поточний вибір), тоді як модель стосується того, яка інформація відображається.
Калеб

1
@MattFenwick Ось що я маю на увазі щодо «аромату» ... Саме те, що ви зберігаєте в контролері, і те, що в моделі, - це питання смаку та умовності. У програмі Cocoa / Cocoa Touch звичайно зберігати в контролері такі речі, як поточний вибір і навіть налаштування користувача. MVC, який використовується в деяких веб-рамках, може містити майже все в моделі та дуже мало в контролері. YMMV.
Калеб

4
@MatthewFlynn Більшість погодиться з вами, але IMO, люди сприймають бізнес-логіку як більш широку категорію, ніж це повинно бути. Контролер обробляє логіку програми, яку люди часто плутають із бізнес-логікою. В ідеальному розділенні проблем, я повинен мати можливість повторно використовувати модельний об’єкт у зовсім іншій архітектурі додатків, що обслуговує ті самі бізнес-цілі без зміни бізнес-об’єкта. Все, що потрібно зробити, - це використовувати інтерфейс і робити власну справу з поверненими та обробленими даними та транзакціями.
Ерік Реппен

1
@MattFenwick: Розгляньте багатокористувацьку програму. Очевидним моментом провести межу між моделлю та контролером є те, що модель обробляє загальний стан та контролер місцевого стану. Поточний вибір локальний, тому він переходить у контролер.
Ян Худек

4

MVC - модель, яка описує розумний спосіб взаємодії об'єктів; це сам по собі не метаклас. При цьому ОО полягає в описі поведінки та даних суб'єктів, а також взаємодії цих суб'єктів. Йдеться не про об'єднання всієї системи в один масивний об’єкт.


2

Контролер не представляє поведінку моделі. Контролери взагалі представляють поведінку всієї програми - що може робити користувач і що може бачити користувач.

Неправильно розглядати контролери та моделі як одну. Вони мають різні цілі, різну семантику і тому не повинні об'єднуватися в один об'єкт.


2

Модельний рівень - це не просто дані, а рівень контролера - це лише логіка.

Шар контролера матиме повну колекцію об'єктів для своїх цілей. Будуть об'єкти для отримання вхідних даних із перегляду та перетворення цього вводу у форму, яку модель може обробити. Структура Java Struts має хороший приклад цього у своїй моделі Action / Form. Форма заповнюється користувачем, а потім передається в дію. Дія бере ці дані та використовує їх для маніпулювання моделлю.

Таким же чином, рівень моделі не складається повністю з даних. Наприклад, візьміть об’єкт "Користувач" - вам може знадобитися код, який отримує користувач із бази даних, або код для асоціації користувача з замовленням або для підтвердження того, що адреса користувача знаходиться в межах сфери послуг вашої компанії ... ви отримуєте картина. Це не логіка контролера. Це бізнес-логіка, і багато хто змусив її розділити рівень моделі на кілька шарів, таких як Сервісний або Менеджер-шари для бізнес-логіки, DAO (Об'єкт доступу до бази даних) для доступу до бази даних та інші.

MVC не є методом організації окремих операцій моделі. Він працює на більш високому рівні, ніж це - це метод організації способу доступу до програми. Перегляд призначений для представлення даних та людських дій для їх маніпулювання, Контролер - це переклад між діями користувача та різними поглядами, а Модель - там, де перебувають бізнес-дані та ділові причини їх існування.


2

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

У MVC функціональність для відображення фрагмента даних (подання) зберігається окремо від даних (модель). Чому так? Це спеціально для того, щоб логіку відображення можна було змінити без необхідності зміни базових даних. Це дозволяє легко змінювати представлення даних, коли вам потрібно зробити різну презентацію одних і тих же даних: або коли характеристики апаратного забезпечення дисплея змінюються: або при переході з Windows на Linux; або коли ви хочете, щоб двоє людей мали два різні способи перегляду одних і тих же даних.

MVC не суперечить OOP - він фактично випливає з правильного застосування Об'єктно-орієнтованих принципів.


0

Я вважаю, що ви плутаєте стійкі дані, пов'язані з об'єктом моделі, з даними програми з баз даних, з якими взаємодіє модель. Модель містить ділову логіку та правила роботи з базами даних та проведення транзакцій. Він може встановлювати та перевіряти внутрішні прапори стану, наприклад, чи є продажі сьогодні, чи користувач має право на статус VIP, а потім відповідно до логіки гілки, коли настає час отримати доступ, встановити чи маніпулювати даними або здійснити покупку. Це ті прапори, про які ми говоримо, коли ми обговорюємо об'єкти з точки зору інкапсуляції набору методів та стійких значень чи даних.

Подібно до того, як модельний об’єкт підтримує дані для встановлення того, які правила ведення бізнесу діють, контролер IMO повинен підтримувати більш загальні дані про стан додатків, що стосуються того, як має поводитись додаток, наприклад, чи користувач увійшов у систему чи має дійсний кредит дані картки на місці. Модельні методи визначають в першу чергу стан цих речей, але має сенс для контролера підтримувати прапори, що стосуються загального потоку додатків, якщо вони не застосовуються до того, як ведеться бізнес або проводяться транзакції даних. Визначивши, що вони не ввійшли в систему, навіть не обтяжуйте модель перевіркими стану користувача, поки не стане зрозумілою ще одна спроба входу.

Так само і з належним об'єктом перегляду порівняно з типовішими шаблонами HTML, які ви бачите в більшості веб-рамок на серверній стороні. Після завантаження кольорових налаштувань користувача, це має бути представлення, яке утримує ці дані та виконує їх. Завантаження, перевірка та зміна налаштувань - це всі проблеми моделі, але вони можуть бути проблемами моделей лише один раз, поки не відбудуться зміни.

ІМО, нічого не говорить про те, що контролери не можуть бути складеними об'єктами з видами та моделями як внутрішні сукупні об'єкти. Це насправді має сенс, якщо ви застосовуєте MVC у меншому масштабі, як заводський віджет UI, оскільки контролер є ідеальним місцем для викриття інтерфейсу до об’єктів додатків вищого рівня, захоплюючи дані та логіку деталей взаємодії перегляду та моделі. Це насправді не має сенсу для монолотичних об’єктів додатків, де контролер справді є об'єктом найвищого рівня.


0

Як я це розумію; Аргумент - це архітектура, заснована на компонентах та OOP. І не потрапляючи в релігійну війну, я думаю, що вони обидва описують одне і те ж; просто дивлячись на це з різних ракурсів.

Наприклад, вся суть OOP / OOD полягає в тому, щоб зробити ваш код більш модульним і багаторазовим. Так?

Яка саме мета складової архітектури. Тож вони більше схожі на все інше.

Я думаю, що MVC - це лише природна еволюція ООП, і наважуся це сказати; кращий спосіб впорядкувати свої об’єкти, відокремити проблеми та повторно використовувати код.


Я б сказав, що MVC та архітектура, що базується на компонентах, є моделями дизайну, що не є сферами підходів до ООП, в той час як OOD / OOP - це просто плутанина і стикання шкіл думки та малакадемії щодо того, як використовувати повсюдне повсюдне програмування будувати належним чином. Порівнювати дві категорії речей - це порівнювати квадрати та ручку, яку ви використовували для малювання квадратів.
Ерік Реппен

-1

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

Отже, я думаю, що справжнє питання є; чи ми більш схильні до процесуального коду при використанні шаблону MVC.

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


-1

Не проти, але також OOP не потрібен для MVC.

Оскільки контролери, які зазвичай представлені класом, не містять даних. Для яких достатньо було б чистих функцій.

Якщо ви йдете далі і відокремлюєте дані від поведінки, наприклад, скажімо, що моделі працюють лише на даних бази даних, які вони отримують щоразу, коли викликається їх функція (що відповідає за маніпулювання даними) (замість того, щоб зберігати певні дані в екземплярі поля) - тоді ви можете сказати те саме для моделей.

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


Ха-ха, я бачу, у деяких людей болить **, стикаючись з фактами. Занадто багато зусиль робити власні рамки з OOP? Не витримаєте втрачений час? Найпростіші відповіді - найкращі.
luke1985

Не впевнений, чому ця відповідь має зворотні відгуки. Він каже, що вони не пов'язані між собою і не є "анти". Здається, досить точно.
mwilcox

-3

На мою думку, ООП має недолік, оскільки оскільки (дані та поведінка) формуються як одна сутність (клас), це демонструє більше ефекту сполучення, ніж згуртованості. Тоді як MVC, з іншого боку, має Модель, що містить ... (Beans, DAOs, Інші класи логіки), Контролер, який визначає, яким чином повинен керувати управління, а Views для визначення способу відображення даних подаються відокремлено. Виходячи з цього, незалежно від того, якщо проект занадто великий, щоб підготуватися, його можна легко зробити як окремий суб'єкт, окрім як змішатись на відміну від ООП. Проблема вирішується за логічним малюнком подібно до стратегії поділу n conquer, і MVC слідує цьому якнайменше.


це лише ваша думка чи ви можете якось це підкріпити?
гнат
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.