Як я можу відокремити інтерфейс користувача від ділової логіки, зберігаючи ефективність?


19

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

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

Хіба це не неймовірно неефективно? У вас уже були об’єкти, з яких ви хотіли вибрати один. Якщо ви подали у форму цілі об'єкти, а потім повернули певний об'єкт, вам не доведеться повторно його повторно, оскільки форма вже повертає посилання на цей об’єкт.

Більше того, якщо я помиляюся, і ви насправді повинні надіслати весь об’єкт у форму, як я можу ізолювати інтерфейс користувача від логіки?


Яким чином це було б неефективно? У будь-якому випадку, ви повинні показати рядкове подання користувачеві і відобразити його відповідь на оригінальний об'єкт.
Саймон Берго

Проблема полягає в тому, що для роботи із зазначеним об'єктом мені доведеться отримати його знову після того, як користувач вибрав його.
Урі

Відповіді:


34

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

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

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

Вільне з'єднання означає, що A знає B, але B не знає А. Іншими словами, дві залучені сторони грають різні клієнтські та серверні ролі, де клієнт знає сервер, але сервер не знає клієнта.

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

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

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

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


5

Ви повинні відокремлювати кожен фрагмент моделі, перегляду та контролера, але немає жодної причини, чому ви не можете (наприклад) передавати об'єкти моделі між контролером та поданням.

Тож у вашому випадку Hamburgerоб’єкти були б частиною Моделі. Потім ви використовуєте контролер для отримання необхідного списку Hamburgers і передаєте ці об'єкти в режим перегляду (комбобокс) для відображення. Коли ваш користувач обрав гамбургер, ви можете знову передати Hamburgerоб'єкт назад в Контролер для обробки.

Справа в тому, що ви все ще можете перевірити Hamburgerлогіку "отримання " та логіку "обробити Hamburger" окремо від фактичного відображення гамбургерів.


Я розумію. Однак тоді, якщо я зміню клас Hamburguer, чи не доведеться також змінювати код форми, що стосується гамбурзьких об’єктів? Де тоді поділ UI-Logic?
Урі

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