Принцип MVC у web-програмуванні. Повертаємось до реалізації MVC. Загальні правила вибору патерну

Багато хто починає писати проект для роботи з єдиним завданням, не маючи на увазі, що це може вирости в розраховану на багато користувачів систему управління, ну припустимо, контентом або боронь бог, виробництвом. І все ніби здорово і класно, все працює, поки не починаєш розуміти, що той код, який написаний - складається цілком і повністю з милиць і хардкод. Код перемішаний з версткою, запитами та милицями, що не піддається іноді навіть прочитанню. Виникає нагальна проблема: при додаванні нових фіч, доводиться з цим кодом дуже довго і довго возитися, згадуючи «а що ж там таке написано було?» і проклинати себе у минулому.

Ви, можливо, навіть чули про шаблони проектування і навіть гортали ці прекрасні книги:

  • Е. Гамма, Р. Хелм, Р. Джонсон, Дж. Вліссідесс «Прийоми об'єктно орієнтованого проектування. Паттерни проектування»;
  • М. Фаулер "Архітектура корпоративних програмних додатків".
А багато хто, не злякавшись величезних посібників і документацій, намагався вивчити якийсь із сучасних фреймворків і зіткнувшись зі складністю розуміння (через наявність безлічі архітектруних концепцій хитро пов'язаних між собою) відклали вивчення та застосування сучасних інструментів у «довгу скриньку».

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

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

1. Теорія Шаблон MVC описує простий спосіб побудови структури програми, метою якого є відокремлення бізнес-логіки від інтерфейсу користувача. В результаті додаток легше масштабується, тестується, супроводжується і звичайно ж реалізується.

Розглянемо концептуальну схему шаблону MVC (на мій погляд – це найбільш вдала схема з тих, що я бачив):

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

Типову послідовність роботи MVC-програми можна описати так:

  • При заході користувача на веб-ресурс, скрипт ініціалізації створює екземпляр програми та запускає його на виконання.
    При цьому відображається вигляд, скажімо, головної сторінки сайту.
  • Програма отримує запит від користувача та визначає запитані контролер та дію. У разі головної сторінки виконується дія за замовчуванням ( index).
  • Додаток створює екземпляр контролера та запускає метод дії,
    в якому, наприклад, містяться виклики моделі, які зчитують інформацію з бази даних.
  • Після цього дія формує подання з даними, отриманими з моделі і виводить результат користувачеві.
  • Модель - містить бізнес-логіку програми та включає методи вибірки (це можуть бути методи ORM), обробки (наприклад, правила валідації) та надання конкретних даних, що найчастіше робить її дуже товстою, що цілком нормально.
    Модель не має безпосередньо взаємодіяти з користувачем. Усі змінні, що стосуються запиту користувача, повинні оброблятися в контролері.
    Модель не повинна генерувати HTML або інший код відображення, який може змінюватись залежно від потреб користувача. Такий код має оброблятися у видах.
    Одна й та сама модель, наприклад: модель аутентифікації користувачів може використовуватися як у користувальницькій, і у адміністративної частини докладання. У такому разі можна винести загальний кодв окремий клас і успадковуватись від нього, визначаючи в спадкоємцях специфічні для додатків методи.

    Вигляд – використовується для завдання зовнішнього відображення даних, отриманих з контролера та моделі.
    Види містять HTML-розмітку та невеликі вставки PHP-коду для обходу, форматування та відображення даних.
    Не повинні безпосередньо звертатися до бази даних. Цим мають займатися моделі.
    Не повинні працювати з даними, отриманими із запиту користувача. Це завдання має виконувати контролер.
    Може безпосередньо звертатися до властивостей та методів контролера або моделей, щоб отримати готові до виведення даних.
    Види зазвичай поділяють на загальний шаблон, що містить розмітку, загальну для всіх сторінок (наприклад, шапку і підвал) та частини шаблону, які використовують для відображення даних, що виводяться з моделі або відображення форм введення даних.

    Контролер - сполучна ланка, що з'єднує моделі, види та інші компоненти робочий додаток. Контролер відповідає за обробку запитів користувача. Контролер не повинен містити SQL-запитів. Їх краще тримати у моделях. Контролер не повинен містити HTML та іншу розмітку. Її варто виносити у види.
    У добре спроектованому MVC-додатку контролери зазвичай дуже тонкі і містять лише кілька десятків рядків коду. Чого не скажеш про Stupid Fat Controllers (SFC) у CMS Joomla. Логіка контролера досить типова і більшість її виноситься в базові класи.
    Моделі, навпаки, дуже товсті та містять більшу частину коду, пов'язану з обробкою даних, т.к. структура даних та бізнес-логіка, що міститься в них, зазвичай досить специфічна для конкретної програми.

    1.1. Front Controller та Page Controller У більшості випадків, взаємодія користувача з web-програмою проходить за допомогою переходів за посиланнями. Подивіться зараз на адресний рядок браузера – за цим посиланням ви отримали цей текст. За іншими посиланнями, наприклад, що знаходяться праворуч на цій сторінці, ви отримаєте інший вміст. Таким чином, посилання надає конкретну команду web-додатку.

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

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

    Приблизний код обробки у такому разі:
    switch($_GET["action"]) ( case "about" : require_once("about.php"); // сторінка "Про нас" break; case "contacts" : require_once("contacts.php"); // сторінка "Контакти" break; case "feedback" : require_once("feedback.php"); // сторінка "Зворотній зв'язок" break; default: require_once("page404.php"); // сторінка "404" break;
    Думаю, майже все так робили раніше.

    З використанням движка маршрутизації URL ви зможете для відображення тієї ж інформації налаштувати програму на прийом таких запитів:
    http://www.example.com/contacts/feedback

    Тут contacts є контролер, а feedback - це метод контролера contacts, що відображає форму зворотного зв'язку і т.д. Ми ще повернемося до цього питання у практичній частині.

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

    2. Практика Для початку створимо наступну структуруфайлів та папок:


    Забігаючи наперед, скажу, що в папці core зберігатимуться базові класи Model, View та Controller.
    Їхні нащадки будуть зберігатися в директоріях controllers, models і views. Файл index.php це точка в ходу додатку. Файл bootstrap.php ініціює завантаження програми, підключаючи всі необхідні модулі та ін.

    Ітимемо послідовно; відкриємо файл index.php і наповнимо його наступним кодом:
    ini_set("display_errors", 1); require_once "application/bootstrap.php";
    Тут питань виникнути не повинно.

    Потім відразу ж перейдемо до фалу bootstrap.php :
    require_once "core/model.php"; require_once "core/view.php"; require_once "core/controller.php"; require_once "core/route.php"; Route::start(); // запускаємо маршрутизатор
    Перші три рядки підключатимуть поки що неіснуючі файли ядра. Останні рядкипідключають файл із класом маршрутизатора та запускають його на виконання викликом статичного методу start.

    2.1. Реалізація маршрутизатора URL Поки що відхилимося від реалізації патерну MVC і займемося мрашрутизацією. Перший крок, який нам потрібно зробити, записати наступний код в .htaccess :
    RewriteEngine On RewriteCond %(REQUEST_FILENAME) !-f RewriteCond %(REQUEST_FILENAME) !-d RewriteRule .* index.php [L]
    Цей код перенаправить обробку всіх сторінок на index.php, що нам потрібно. Пам'ятаєте у першій частині ми говорили про Front Controller?!

    Маршрутизацію ми помістимо в окремий файл route.php до директорії core. У цьому файлі опишемо клас Route, який запускатиме методи контролерів, які у свою чергу генеруватимуть вигляд сторінок.

    Вміст файлу route.php

    class Route ( static function start() ( // контролер і стандартна дія $controller_name = "Main"; $action_name = "index"; $routes = explode("/", $_SERVER["REQUEST_URI"])); // отримуємо ім'я контролера if (!empty($routes)) ( $controller_name = $routes; ) // отримуємо ім'я екшену if (!empty($routes)) ( $action_name = $routes; ) // додаємо префікси $model_name = " Model_".$controller_name; $controller_name = "Controller_". $controller_name; $action_name = "action_". ".php"; $model_path = "application/models/". $model_file; if(file_exists($model_path)) ( include "application/models/". ($controller_name).".php"; $controller_path = "application/controllers/".$controller_file; if(file_exists($controller_path)) ( include "application/controllers/".$controller_file; ) else ( /* правильно було б кинути тут виняток, але для спрощення відразу зробимо редирект на сторінку 404 */ Route::ErrorPage404(); ) // створюємо контролер $controller = new $controller_name; $action = $action_name; if(method_exists($controller, $action)) ( // викликаємо дію контролера $controller->$action(); ) else ( // тут також розумніше було б кинути виняток Route::ErrorPage404(); ) ) function ErrorPage404( ) ( $host = "http://".$_SERVER["HTTP_HOST"]."/"; header("HTTP/1.1 404 Not Found"); header("Status: 404 Not Found"); header("Location:".$host."404");


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

    В елементі глобального масиву$_SERVER["REQUEST_URI"] міститься повна адресаяким звернувся користувач.
    Наприклад: example.ru/contacts/feedback

    За допомогою функції explodeпровадиться поділ адреси на складові. В результаті ми отримуємо ім'я контролера, для наведеного прикладу це контролер contactsта ім'я дії, у нашому випадку - feedback.

    Далі підключається файл моделі (модель може бути відсутнім) і файл контролера, якщо такі є і нарешті, створюється екземпляр контролера і викликається дія, знову ж таки, якщо вона була описана в класі контролера.

    Отже, під час переходу, наприклад, за адресою:
    example.com/portfolio
    або
    example.com/portfolio/index
    роутер виконає такі дії:

  • підключить файл model_portfolio.php із папки models, що містить клас Model_Portfolio;
  • підключить файл controller_portfolio.php із папки controllers, що містить клас Controller_Portfolio;
  • створить екземпляр класу Controller_Portfolio і викличе стандартну дію - action_index, описану в ньому.
  • Якщо користувач спробує звернутися на адресу неіснуючого контролера, наприклад:
    example.com/ufo
    то його перекине на сторінку «404»:
    example.com/404
    Те саме станеться, якщо користувач звернеться до дії, яка не описана в контролері.2.2. Повертаємося до реалізації MVC Перейдемо в папку core і додамо до файлу route.php ще три файли: model.php, view.php та controller.php


    Нагадаю, що вони будуть містити базові класи, написання яких ми зараз і приступимо.

    Зміст файлу model.php
    class Model ( public function get_data() ( ) )
    Клас моделі містить єдиний порожній метод вибірки даних, який перекриватиметься у класах нащадків. Коли ми створюватимемо класи нащадки, все стане зрозуміліше.

    Зміст файлу view.php
    class View ( //public $template_view; // тут можна вказати загальний вигляд за замовчуванням. function generate($content_view, $template_view, $data = null) ( /* if(is_array($data))) в змінні extract($data); ) */ include "application/views/".$template_view; ) )
    Не важко здогадатися, що метод generateпризначений на формування виду. До нього передаються такі параметри:

  • $content_file - види, що відображають контент сторінок;
  • $template_file - загальний всім сторінок шаблон;
  • $ data - масив, що містить елементи контенту сторінки. Зазвичай заповнюється у моделі.
  • Функцією include динамічно підключається загальний шаблон (вид), всередині якого вбудовуватиметься вигляд
    для відображення вмісту конкретної сторінки.

    У нашому випадку загальний шаблон міститиме header, menu, sidebar і footer, а контент сторінок буде в окремому вигляді. Знову ж таки це зроблено для спрощення.

    Вміст файлу controller.php
    class Controller ( public $model; public $view; function __construct() ( $this->view = new View(); ) function action_index() ( ) )
    Метод action_index- це дія, що викликається за умовчанням, ми перекриємо при реалізації класів нащадків.

    2.3. Реалізація класів нащадків Model і Controller, створення View"s Тепер починається найцікавіше! Наш сайт-візитка складатиметься з наступних сторінок:
  • Головна
  • Послуги
  • Портфоліо
  • Контакти
  • А також сторінка «404»
  • Для кожної зі сторінок є свій контролер з папки controllers та вид з папки views. Деякі сторінки можуть використовувати модель або моделі з папки.


    На попередньому малюнку окремо виділено файл template_view.php – це шаблон, що містить загальну для всіх сторінок розмітку. У найпростішому випадку він міг би виглядати так:
    Головна
    Для надання сайту презентабельного вигляду зверстаємо CSS шаблон і інтегруємо його в наш сайт шляхом зміни структури HTML-розмітки та підключення CSSта JavaScript файлів:

    Наприкінці статті, у розділі «Результат», наводиться посилання на GitHub-репозиторій із проектом, в якому виконані дії з інтеграції простенького шаблону.

    2.3.1. Створюємо головну сторінку Почнемо з контролера controller_main.php , ось його код:
    class Controller_Main extends Controller ( function action_index() ( $this->view->generate("main_view.php", "template_view.php"); ) )
    У метод generateекземпляра класу View передаються імена файлів загального шаблону та виду з контентом сторінки.
    Крім індексної дії в контролері, звичайно ж можуть утримуватися й інші дії.

    Файл із загальним виглядом ми розглянули раніше. Розглянемо файл контенту main_view.php :
    Ласкаво просимо!

    ОЛОЛОША TEAM - команда першокласних фахівців у галузі розробки веб-сайтів з багаторічним досвідом колекціонування мексиканських масок, бронзових та кам'яних статуй з Індії та Цейлону, барельєфів та статуй, створених майстрами Екваторіальної Африки п'ять-шість століть тому...


    Тут міститься проста розмітка без будь-яких PHP-дзвінків.
    Для відображення головної сторінки можна скористатися однією з наступних адрес:

    Приклад з використанням виду, що відображає дані, отримані з моделі, ми розглянемо далі.

    2.3.2. Створюємо сторінку «Портфоліо» У нашому випадку, сторінка «Портфоліо» - це єдина сторінка, що використовує модель.
    Модель зазвичай включає методи вибірки даних, наприклад:
  • методи нативних бібліотек pgsql чи mysql;
  • методи бібліотек, що реалізують абстракіцю даних Наприклад, методи бібліотеки PEAR MDB2;
  • методи ORM;
  • методи для роботи з NoSQL;
  • та ін.
  • Для простоти, ми не будемо використовувати SQL-запити або ORM-оператори. Натомість ми семулюємо реальні дані і відразу повернемо масив результатів.
    Файл моделі model_portfolio.php помістимо до папки models. Ось його вміст:
    class Model_Portfolio extends Model ( public function get_data() ( return array(array("Year" => "2012", "Site" => "http://DunkelBeer.ru", "Description" => "Промо-сайт темного пива Dunkel від німецького виробника Löwenbraü, що випускається в Росії, пивоварною компанією "CАН ІнБев"."), array("Year" => "2012", "Site" => "http://ZopoMobile.ru", "Description" => "Російськомовний каталог китайських телефонівкомпанії Zopo на базі Android OS та аксесуарів до них."), // todo); ) )

    Клас контролера моделі міститься у файлі controller_portfolio.php , ось його код:
    class Controller_Portfolio extends Controller ( function __construct() ( $this->model = new Model_Portfolio(); $this->view = new View(); ) function action_index() ( $data = $this->model->get_data( ); $this->view->generate("portfolio_view.php", "template_view.php", $data); ) )
    У змінну dataзаписується масив, що повертається методом get_data, що ми розглядали раніше.
    Далі ця змінна передається як параметр методу generate, в який також передаються: ім'я файлу із загальним шаблоном та ім'я файлу, що містить вигляд c контентом сторінки.

    Вигляд містить контент сторінки знаходиться у файлі portfolio_view.php.
    Портфоліо

    Всі проекти в таблиці є вигаданими, тому навіть не намагайтеся перейти за наведеними посиланнями.
    РікПроектОпис


    Тут все просто, вигляд відображає дані, отримані з моделі.

    2.3.3. Створюємо інші сторінки Інші сторінки створюються аналогічно. Їх код доступний у репозиторії на GitHub, посилання на який наводиться наприкінці статті, у розділі «Результат».3. Результат А ось що вийшло в результаті:

    Скріншот сайту-візитки, що вийшов.



    Посилання на GitHub: https://github.com/vitalyswipe/tinymvc/zipball/v0.1

    А ось у цій версії я накидав такі класи (і відповідні їм види):

    • Controller_Login в якому генерується вид з формою для введення логіну та пароля, після заповнення якої проводиться процедура аутентифікації і в разі успіху користувач перенаправляється в адмінку.
    • Contorller_Admin з індексною дією, в якій перевіряється, чи був користувач раніше авторизований на сайті як адміністратор (якщо був, то відображається вид адмінки) і дією logout для розлогінування.
    Аутентифікація та авторизація - це інша тема, тому тут вона не розглядається, а лише наводиться посилання вказане вище, щоб було від чого відштовхнутися. Висновок Шаблон MVC використовується як архітектурна основа в багатьох фреймворках і CMS, які створювалися для того, щоб мати можливість розробляти якісно більше складні рішенняза коротший термін. Це стало можливо завдяки підвищенню рівня абстракції, оскільки є межа складності конструкцій, якими може оперувати людський мозок.

    Але використання веб-фреймворків, типу Yii або Kohana, що складаються з декількох сотень файлів, при розробці простих веб-додатків (наприклад, сайтів-візиток) не завжди доцільно. Тепер ми вміємо створювати красиву MVC модель, щоб не перемішувати Php, Html, CSS та JavaScript кодв одному файлі.

    Ця стаття є скоріше відправною точкою для вивчення CMF, ніж прикладом чогось істинно правильного, що можна взяти за основу свого веб-додатку. Можливо, вона навіть надихнула Вас і ви вже подумуєте написати свій мікрофреймворк або CMS, засновані на MVC. Але, перш ніж винаходити черговий велосипед з «блекджеком і повями», ще раз подумайте, чи може ваші зусилля розумніше спрямувати на розвиток і на допомогу спільноті вже існуючого проекту?!

    PS: Стаття була переписана з урахуванням деяких зауважень, які залишаються в коментарях. Критика виявилася дуже корисною. Судячи з відгуку: коментарям, зверненням в особу і кількості користувачів додали пост у обране витівка написати цей пост виявилося не таким вже й поганим. На жаль, неможливо врахувати всі побажання і написати більше і докладніше через брак часу ... але можливо це зроблять ті таємничі особистості, хто мінусував початковий варіант. Успіхів у проектах!

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

    Теги: Додати теги

    Добрий день, шановні колеги. У цій статті я хотів би розповісти про своє аналітичне розуміння відмінностей патернів MVC, MVP та MVVM. Написати цю статтю мене спонукало бажання розібратися в сучасних підходах при розробці великого програмного забезпечення та відповідних архітектурні особливості. На поточному етапі своїх кар'єрних сходів я не є безпосереднім розробником, тому стаття може містити помилки, неточності та непорозуміння. Заінтриговані, як аналітики бачать, що роблять програмісти та архітектори? Тоді ласкаво просимо під кат.

    Посилання Перше, з чого я хотів би почати - це посилання на зовнішні матеріали, якими я керувався в процесі написання цієї статті:
    У часи, коли сонце світило яскравіше, а трава була зеленішою, на той момент команда студентів, як автор цієї статті, розробляли програмне забезпечення, писав сотні рядків коду безпосередньо в інтерфейсі продукту. Іноді використовувалися сервіси та менеджери для роботи з даними, і тоді рішення виходило з використанням патерну Document-View. Підтримка такого коду вимагала колосальних витрат, тому нового розробника треба навчити (розповісти), який код за що в продукті відповідає, і про яке модульне тестування і мови не було. Команда розробки – це 4 особи, які сидять в одній кімнаті.
    Минув час, змінювалася робота. Додатки, що розроблялися, ставали більшими і складнішими, з однієї згуртованої команди розробників стало багато різних командрозробників, архітекторів, юзабілістів, дизайнерів та PMів. Тепер кожен відповідальний за свою сферу: GUI, бізнес-логіка, компоненти. З'явився відділ аналізу, тестування, архітектури. Вартість розробки програмного забезпечення зросла в сотні і навіть тисячі разів. Такий підхід до розробки вимагає наявність стійкої архітектури, яка синхронізувала б різні функціональні області продукту між собою. Патерни Враховуючи мету зменшення трудовитрат на розробку складного програмного забезпечення, припустимо, що необхідно використовувати готові уніфіковані рішення. Адже шаблонність дій полегшує комунікацію між розробниками, дозволяє посилатися на відомі конструкції, знижує кількість помилок.
    За словами Вікіпедії, патерн (англ. design pattern) - повторна архітектурна конструкція, що представляє собою вирішення проблеми проектування в рамках деякого контексту, що часто виникає.

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

    Вперше патерн MVCз'явився у мові SmallTalk. Розробники мали придумати архітектурне рішення, яке дозволяло б відокремити графічний інтерфейсвід бізнес-логіки, а бізнес-логіку від даних. Таким чином, у класичному варіанті MVC складається з трьох частин, які і дали йому назву. Розглянемо їх:

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

    Модель має такі ознаки:

    • Модель – це бізнес-логіка програми;
    • Модель має знання про себе саму і не знає про контролерів і уявлення;
    • Для деяких проектів модель – це просто шар даних (DAO, база даних, XML-файл);
    • Для інших проектів модель - менеджер бази даних, набір об'єктів або просто логіка програми;
    Подання (View) До обов'язків Подання входить відображення даних, отриманих від Моделі. Однак уявлення не може безпосередньо впливати на модель. Можна говорити, що уявлення має доступом «лише читання» до даних.

    Подання має такі ознаки:

    • У поданні реалізується відображення даних, що виходять від моделі будь-яким способом;
    • У деяких випадках подання може мати код, який реалізує деяку бізнес-логіку.
    Приклади представлення: HTML-сторінка, WPF форма, Windows Form.
    • Model-View-Controller
    • Model-View-Presenter
    • Model-View-View Model

    Розглянемо та порівняємо кожен із них.

    Model-View-Presenter

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

    Ознаки презентера:

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

    Реалізація:
    Кожна вистава має реалізовувати відповідний інтерфейс. Інтерфейс подання визначає набір функцій і подій, необхідних взаємодії з користувачем (наприклад, IView .ShowErrorMessage(string msg)). Презентер повинен мати посилання реалізацію відповідного інтерфейсу, яку зазвичай передають у конструкторі.
    Логіка вистави повинна мати посилання на екземпляр презентера. Всі події уявлення передаються для обробки презентатором і практично ніколи не обробляються логікою уявлення (в т.ч. створення інших уявлень).

    Приклад використання Windows Forms.

    Model-View-View Model

    Даний підхід дозволяє пов'язувати елементи уявлення з властивостями та подіями View-моделі. Можна стверджувати, кожен шар цього патерну не знає про існування іншого шару.

    Ознаки View-моделі:

    • Двостороння комунікація з поданням;
    • View-модель – це абстракція уявлення. Зазвичай означає, що властивості подання збігаються з властивостями View-моделі/моделі
    • View-модель не має посилання на інтерфейс уявлення (IView). Зміна стану View-моделі автоматично змінює уявлення та навпаки, оскільки використовується механізм зв'язування даних (Bindings)
    • Один екземпляр View-моделі пов'язаний з одним відображенням.

    Реалізація:
    При використанні цього патерну уявлення не реалізує відповідний інтерфейс (IView).
    Подання повинно мати посилання джерело даних (DataContex), яким у разі є View-модель. Елементи уявлення пов'язані (Bind) з відповідними властивостями та подіями View-моделі.
    У свою чергу, View-модель реалізує спеціальний інтерфейс, який використовується для автоматичного оновленняелементів подання. Прикладом такого інтерфейсу WPF може бути INotifyPropertyChanged.

    Приклад використання: WPF

    Model-View-Controller
    Основна ідея цього патерну в тому, що і контролер і уявлення залежать від моделі, але модель не залежить від цих двох компонентів.

    Ознаки контролера

    • Контролер визначає, які уявлення має бути відображено в даний момент;
    • Події подання можуть вплинути тільки на контролер. Контролер може вплинути на модель і визначити інше уявлення.
    • Можливо кілька уявлень лише одного контролера;

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

    Приклад використання: MVC ASP.NET

    Резюме Реалізація MVVM і MVP-патернів, на перший погляд, виглядає досить простою схожою. Проте, для MVVM зв'язування подання з View-моделлю здійснюється автоматично, а MVP - необхідно програмувати
    MVC, мабуть, має більше можливостей з управління поданням. Загальні правилавибору патерну MVVM
    • Використовується у ситуації, коли можливе зв'язування даних без необхідності введення спеціальних інтерфейсів подання (тобто відсутня необхідність реалізовувати IView);
    • Найчастішим прикладом є технологія WPF.
    MVP
    • Використовується в ситуації, коли неможливе зв'язування даних (не можна використовувати Binding);
    • Найчастішим прикладом може бути використання Windows Forms.
    MVC
    • Використовується в ситуації, коли зв'язок між представленням та іншими частинами програми неможливий (і Ви не можете використовувати MVVM або MVP);
    • Частим прикладом використання може бути ASP.NET MVC.
    Заключение Наприкінці, автор цієї статті хотів би відзначити, що суворо дотримуватися лише одному патерну - який завжди найкращий вибір. Наприклад, уявіть, що Ви хотіли б використовувати MVVM для розробки програм з використанням WindowsФорми через властивість контролю Bindings. Ваша мета - це відокремити уявлення від бізнес логіки та логіки, яка їх пов'язує. Додаток має бути легко тестований і підтримуваний, а для аналітиків - зрозумілий (адже на питання «в чому вимірюється робота жорсткогодиска» існує єдина правильна відповідь - у Джоулях (абстрактний приклад Моделі -> Уявлення)).

    Дуже дякую за приділений час, приємного читання!

    Що таке MVC?

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

    Але якщо у нас є користувач, значить повинен бути інтерфейс користувача. Що таке інтерфейс? Це суміжний кордон між двома системами. У нашому випадку: з одного боку – програма, з іншого – користувач. Ось вони.

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

    Юзкейси

    Як приклад уявіть термінал для торгівлі на біржі. Користувач терміналу виставляє заявку, в якій вказує, що хоче купити акції компанії «Світлий шлях» в кількості 20 штук за ціною 1500 рублів за акцію. Також вказує, що заявка дійсна протягом чотирьох годин, і з якого з його рахунків списати гроші у разі успішної угоди.

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

    Але на біржі не можна змінити заявку, у предметній галузі немає такого поняття. Заявку можна лише виставити та скасувати. Щоб дати користувачеві можливість в один клік змінювати заявку, потрібно запам'ятовувати старі значення, знімати заявку, редагувати те, що запам'ятали, і виставляти нову заявку. Така комбінація. Але для користувача вона виглядає як одна проста дія: зміна заявки. Це називається – use case.

    Доповнимо нашу діаграму місцем під юзкейси.

    Ще користувачеві треба дати можливість смикати ці юзкейси та отримувати результат. Це можуть бути кнопки та інші графічні елементи введення-виводу, жести, розпізнавання та синтез мови. Будь-який варіант обміну даними та командами. Вуаля:

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

    Так де ж тут все-таки MVC?

    Все, що залишилося - це тільки роздати знайомі імена компонентам, що утворилися.

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

    Тепер трохи зокрема.

    Це був класичний варіант MVC – Active Model. Буває й так, що модель не повідомляє про зміни. Тоді цей обов'язок бере на себе контролер. Він знає, які маніпуляції здійснює над моделлю, і, очевидно, знає, які зміни в стані моделі можуть бути. Це Passive Model.

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

    За матеріал дякуємо нашому передплатнику Станіславу Іллічову

    У номері

      захисний елемент- Водяний знак: традиції та інновації

      місце зустрічі- Це гроші завтрашнього дня

      точка зору- Прем'єри та тенденції

      ноу-хау- Дволикий захист

      ноу-хау- Весь секрет у лінзах

      документ - Канадський паспорт: мистецтво технологій

      розробки - Захисні волокна: нові можливості

      марки- Зразки, нікель та вірші Бродського

      знаки історії- Листівки: шлях від «поштової телеграми» до агітаційного плакату

      екскурсія- Вірменські драми: гроші ілюструють історію

    Просто перевірити, складно повторити

    У Останніми рокамиГознак активно розробляє та просуває на ринок найбільш ефективні захисні технології. Серед них виділяються два напрями: зі створення елементів, видимих ​​на просвіт, та ознак, отриманих за рахунок поєднання офсетної та металограф

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

    Просвітлені технології

    Водяний знак, що спостерігається в папері в світлі, залишається найбільш популярною захисною ознакою у населення. При цьому він технологічний, а досвід виробництва паперу з водяними знаками обчислюється більш як сімома століттями. Саме тому за останні роки завдяки появі нових технологій виготовлення формних виробів ця захисна ознака набула нового розвитку. Багатотонові водяні знаки практично у всіх модернізованих банкнотах поступилися своїм місцем водяним знакам, отриманим за рахунок комбінування багатотонових та філігранних знаків. Нині ж активно впроваджується технологія отримання водяних знаків з допомогою складних багаторівневих філігранів. Журнал «Водяний знак» неодноразово розповідав про ці водяні знаки. Ця технологія дає можливість отримати не лише контрастні світлі ділянки знака, а й зображення з високою, нетиповою для водяних знаків лінією.

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

    Саме такий підхід було реалізовано у пам'ятній банкноті «Сочі 2014». У прозорому вікні, отриманому за рахунок введення широкої полімерної стрічки в папір під час відливу, виконаний металографським способом оптично-змінний захисний елемент Зебра. При розгляданні на просвіт та плавному повороті банкноти можна побачити, як зображення сніжинки у вікні змінюється з негативного на позитивне.

    А що, якщо не вводити полімерну стрічку для отримання оптично-змінної ознаки, що контролюється на просвіт? Або, по-іншому, як отримати в папері оптично. змінний елемент, що контролюється на просвіт, з використанням традиційних банкнотних технологій? Саме таке завдання було поставлено перед співробітниками Дирекції з захисним технологіямта спеціалістами НДІ Гознака у 2014 році. Ціль очевидна: позбутися «додаткового» елемента – широкої полімерної стрічки та складної технології її введення в папір, тобто зробити захисне рішенняще ефективнішим.

    Завдання виявилося дуже складним, оскільки, з одного боку, на кінцевий результат впливала велика кількість факторів, а, з іншого боку, основні фактори виявилися не тільки тісно пов'язані один з одним, а й перебували в суперечності. Довелося шукати нестандартні рішення. До кінця 2014 року після проведеної науково-дослідної роботи було доведено принципову можливість отримання таких захисних елементів. У 2015 році ФГУП «Гознак» випущено рекламну банкноту «Російський Авангард», представлену заступником генерального директораз науки та розвитку А. Б. Курятниковим у другому номері журналу «Водяний знак» за 2015 рік. У рекламній банкноті реалізований захисний елемент «Силует» – оптично змінний елемент, видимий у світлі, що проходить, і виконаний з використанням традиційних поліграфічних банкнотних технологій у напівпрозорому вікні, отриманому з використанням традиційної технології виготовлення банкнотного паперу. В даний час проводиться робота як з удосконалення технології отримання напівпрозорого вікна, так і з оптимізації дизайну друкованих елементів.

    Гра в кубики

    MVC, MVC+, HMC… Ці абревіатури назв захисних ознак, розроблених у ФГУП «Гознак», регулярно з'являються на сторінках журналу, починаючи з 2004 року. І якщо зібрати всі статті, написані на цю тему, вийде ціла історія народження, становлення та розвитку одного з найефективніших, на наш погляд, захисних напрямків. Особливість цього напряму полягає в тому, що для відтворення захисних елементів використовується комбінація у вигляді узгоджених за геометричними параметрами ліній, надрукованих офсетним та металографським способами друку.

    захисна ознака MVC Moire Variable Color, що з'явилася в модернізованих банкнотах Банку Росії, була призначена, в першу чергу, для захисту від копіювання. Нагадаємо, як працює ознака: на однорідному полі при нахилі банкноти з'являються кольорові муарові смуги. На копії цей оптично-змінний ефект відсутня, тобто або кольорові смуги муарові не з'являються, або виявляються відразу, і картина залишається без змін при будь-яких нахилах і поворотах банкноти. Потенціал цієї ознаки виявився набагато вищим за спочатку передбачуваний завдяки високій стійкості до імітацій, технологічності, зносостійкості та можливостям його подальшої модернізації. Простота його реалізації в банкнотах міської серії модернізації 2004 р. та очікувані фахівцями Гознака у зв'язку з цим швидкі імітації змусили модернізувати цю захисну ознаку у напрямку створення більш складної для відтворення фальшивомонетниками муарової картини, обумовленої застосуванням нелінійної структури ліній та застосуванням комбінації друку. Так виникла наступна генерація оптично-змінної ознаки MVC+. Цей захисний елемент має дві узгоджені між собою області. У нижній області малюнок муара видно під будь-яким кутом, а у верхній області, як і у випадку MVC, він з'являється лише під певним кутом. Дуже важливо знати, що при нахилі банкноти малюнок муара верхньої та нижньої частин повинен утворити одну нерозривну картину без усунення муарових ліній на межі цих двох областей. Крім того, ця захисна ознака посилена касовим рівнем захисту. При розгляді елемента MVC+ під впливом УФ-випромінювання можна спостерігати такий самий муарообразующий ефект, як і при денному світлі. Захисний елемент MVC+ застосований у банкнотах Банку Росії номіналом 1000 та 5000 рублів модернізації 2010 року.

    Паралельно з MVC+ велися розробки нового захисного елемента, що має великий візуальним ефектом. І до 2010 року було створено нову захисну ознаку HMC (Hidden Multi Color), яка стала ще ефективнішим захисним елементом у цій серії ознак. Завдяки зміні геометричних параметрів офсетних та металографських ліній при нахилі банкноти спочатку однорідне поле розбивається на окремі фрагменти, забарвлені у різні кольори. Як кольорові фрагменти використовуються цифри, текстові символи, геометричні фігури, будь-які довільні області. Зазвичай застосовується трохи більше 2–3 кольорів. Важливою особливістюцієї захисної ознаки є можливість додаткової перевіркийого справжності. Якщо запам'ятати кольори, видимі при нахилі банкноти, а потім розгорнути банкноту в її площині на 180 градусів, можна побачити зовсім інші кольори фрагментів. Цей ефект отримано завдяки спеціальній формі ліній та використанню унікального обладнання для виготовлення металографських форм. Як і у елемента MVC+, у захисного елемента HMC існує додатковий касовий рівень автентифікації: під впливом УФ-випромінювання можна побачити такі самі оптично-змінні ефекти, як і при денному світлі. Захисний елемент HMC було впроваджено у захисний комплекс банкноти Банку Росії номіналом 500 рублів модифікації 2010 року.

    Для отримання захисних елементів серії MVC – HMC використовуються металографські лінії із досить великою глибиною рельєфу. У разі дуже високого тиску при металографічного друку папір деформується, приймаючи форму профілю металографічних ліній. Рельєф, що при цьому утворюється, виникає і на лицьовій, і на зворотній стороні друкованого листа. Якщо рельєф лицьової сторони «працює» у захисних ознаках серії MVC – HMC, то оборотний рельєф донедавна не використовувався. Фахівці Гознака запропонували цікаве рішення- Створення оптично-змінних елементів і на лицьовій, і на зворотному боці банкноти при металографічного друку тільки з лицьового боку. Такий елемент було розроблено та реалізовано на рекламній банкноті «195 років Гознака». Докладний описцього елемента, що отримав назву CHMC (Сombined HMC), наведено в журналі «Водяний знак» №3 за 2013 р. Крім отримання оптично-змінних ознак на двох сторонах банкноти за рахунок використання важливої технологічної особливостіофсетної друкарської машини – забезпечення точного приведення друку лицьової та оборотної сторін, – отримано елемент для контролю суміщення лицьової та оборотної сторін. Таким чином, CHMC – це «три в одному», тобто оптичні ознаки з обох сторін банкноти та елемент для контролю суміщення лицьової та оборотної сторін. Важливою особливістю цього елемента є те, що на лицьовій та оборотній сторонах банкноти можна отримувати незалежно як MVC, так і HMC або їх комбінації. Так, на рекламній банкноті «Російський Авангард» на лицьовій стороні застосовано елемент HMC, а на зворотному – комбінацію MVC та HMC.

    Для отримання найкращого візуального ефекту при створенні ознак серії MVC – HMC, особливо HMC, необхідно використовувати для друку офсетних ліній яскраві контрастні кольори. Ідеальний випадок – застосовувати кольори CMY. Однак часто при модернізації банкнот замовник не дозволяє змінювати кольори або використовувати такі яскраві кольори. офсетного друку. Тому доводиться йти на компроміс між дизайном та візуальним ефектом. Особливо це актуально для елемента HMC. Саме для таких «складних» у колірному відношенні банкнот було розроблено дво- і навіть однобарвні оптично-змінні елементи HMC. При цьому однофарбовий елемент формально є двофарбовим, оскільки як друга фарба використовується пробіл, тобто колір паперу. Тому при нахилі банкноти колір не змінюється, з'являється позитивне чи негативне зображення.

    Крім того, будь-який із елементів серії MVC – HMC може бути доповнений прихованим або латентним зображенням.

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

    Розвиток оптично-змінних захисних елементів серії MVC – HMC продовжується. Є нові ідеї. І цілком можливо, що в новій рекламній банкноті або будь-якому тиражному виробі незабаром з'явиться нова реалізація захисної ознаки, заснованої на комбінації офсетного та металографічного друку.

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

    Принцип MVC дозволяє розділити реалізацію логіки програми, зовнішній вигляд(графічний інтерфейс, GUI) та взаємодія з користувачем.

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

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

    Принцип MVC використовують практично всі сучасні фреймворки.

    Розглянемо докладніше компоненти.

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

    View (Вигляд, Подання)описує зовнішній вигляд програми.

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

    Взаємозв'язок можна переглянути на діаграмі:

    Джерело зображення: http://www.wikipedia.org Вимоги до компонентів:

    Моделі:

    • повинні містити властивості, які мають конкретні дані;
    • повинні включати бізнес-логіку (наприклад, правила валідації), щоб переконатися в тому, що дані відповідають пред'явленим вимогам;
    • можуть містити код для роботи з даними.
    Уявлення:
    • повинні, головним чином, містити розмітку, таку як HTML, та простий PHPкод, що використовується для обходу, форматування та відображення даних;
    • не повинні безпосередньо звертатися до бази даних. Цим мають займатися моделі;
    • не повинні безпосередньо звертатися до $_GET , $_POST та інших змінних, які отримуються із запиту користувача. Це завдання має виконувати контролер. Подання повинні використовуватися лише для оформлення даних, отриманих від контролера та моделі;
    • можуть безпосередньо звертатися до властивостей та методів контролера чи моделей. Однак це має робитися лише з метою відображення даних.
    Контролери:
    • можуть звертатися до $_GET , $_POST та інших змінним PHP, одержуваним із запиту користувача;
    • можуть створювати екземпляри моделей та керувати ними. Наприклад, у типовій дії оновлення моделі контролер може спочатку створити екземпляр моделі, потім заповнити його даними з $_POST і, у разі успішного збереження моделі, перенаправити браузер користувача на сторінку створеної моделі. Слід зазначити, що саме збереження моделі має бути реалізовано в класі моделі, а не в контролері;
    • не повинні містити запити SQL. Їх краще тримати у моделях;
    • не повинні містити HTML та іншу розмітку. Її варто винести на уявлення.
    (Вимоги запозичені звідси: http://yiiframework.ru/doc/guide/ru/basics.best-practices)

    Крім концепції MVC існують і багато інших, наприклад MOVE (M odels, O perations, V iews і E vents) - начебто, як еволюція MVC (взято звідси: http://habrahabr.ru/post/147038/), але ці концепції менш поширені.