Про модний термін MVVM.
- 1. MVVM на рівні SQL.
- 2. BLL - Business Layer Logic.
- 3. Linq-to-SQL - універсальна BLL в патерні MVVM.
- 4. MVVM у ASP.NET з використанням EF.
- 5. MVVM у WPF.
- 6. Шаблон коду MVVM у WPF.
Декілька разів у минулому році я стикався з пропозиціями роботи, де використовувалася якась надзвичайно модна технологія MVVM. Я розумію головне, що нічого нового (особливо Мікрософт) вигадати не може, бо він має величезну текучість кадрів, працюють там молоді індуси і вони намагаються щось постійно вигадувати, щоб бути "на слуху". Це більш за все нагадує телефонні компанії, яки вигадують все нові й нові тарифи, які нібито вам допоможуть платити за телефон меньше. Чи банки, які постійно вигадують нібито нові ї нові свої "кредитні продукти", які нібито вам будуть більш корисні, ніж їхні попередні "продукти".
Оскільки у англійскому алфавіті лише 26 букв, то трисимвольних технологій можна вигадати лише 26х25х24 штук, тобто 15 тисяч 600 штук. Це явно не відповідає планам мікрософта і вони вже давно почали вигадувати чотиресимвольні назви. Це дасть можливість молодим індусам (яких вже більше мільярда) більше можливостей для самореалізації - можна буде вигадати аж 358 тисяч 800 технологій. Але й це мало для мільярда індусів, вони інколи використовують вже п'яти і шости-символьні назви своїх "нових" чудо-технологій. Наприклад ODATA - що є найзвичайніший SOAP/WSDL сервіс з крихітною надбудовою, що дозволяє звертатися до цього сервісу через зовнішній URL. Щоб збудувати подібний сервіс для своєї власної програми - мені вистачить години, але щоб прочитати книжку про Odata - не вистачить і місяця. Зато яка можливість самореалізації для молодих індусов, які працюють у мікрософті. І сколько можно підняти інформаційного шуму про "нові революційні продукти" від Мікрософту.
Але у різноманітних технічних інтерв'ю про Odata, MVVM та подібні абревіатури питають нібито це справжні якийсь "нові" технології і тому я подивився детально, що ж означає термін MVVM. Для початку, я знайшов ось такі визначення MVVM:
- MVVM - Quick Guide
- MVVM - IOC Containers and MVVM
- What is the difference between MVC and MVVM?
- Model-View-Presenter (MVP) https://msdn.microsoft.com/en-gb/magazine/dn237302.aspx
Далі я зроблю спробу пояснити термін MVVM настільки просто, настільки це можливо.
1. MVVM на рівні SQL.
Поперше, всі попередні роки існувало визначення Model, звичайно це визначення на рівні SQL означало якусь окрему табличку. Звичайно з окремими таблами у нормалізованій формі працювати незручно, тому з SQL-серверу завжди піднімали дані через View. Так робили ще забагато років до утворення мікрософту, але це й був той самий середній рівень між даними та програмою, яка їх використовує. Тобто у сучасній термінології - наявність рівня View у SQL-сервері - це і є MVVM-технологія.
Звичайно, у будь-який реальній програмі існує велика кількість таких абстракцій як View на рівні SQL. Ось наприклад подивимось на мій найбільш комерційно вдалий проєкт VOTPUSK - там вьюх скільки завгодно. Це і є MVVM.
2. BLL - Business Layer Logic.
Звичайно, що це дуже простий MVVM, який не має якогось розумного функціоналу. Більш-менш розумними були BLL - Business Layer Logic. Звичайно це якийсь власний код, який має специфічні методи.
BLL існували завжди, коли навіть коли ще не існувало Мікрософту. Але коли він з'явився, він теж почав використовувати ці терміни. Ось опис якоїсь моєї власної BLL, зроблений мною ще у 2006-му році, по мотивам якоїсь моєї старовинної проги 2003-року, тобто прошло вже 14 років від того моменту, як навіть на моєму сайті з'явився опис звичайної технології MVVM - Бизнес-объекты на базе типизированных спецколлекций. У цьому випадку GridView, який показував дані на формі, мав біндінг не до якийсь фрагментарних даних моделі, а до проміжного рівня, який ще мав деякі додаткові можливості-сервіси. Тобто це чистий MVVM.
3. Linq-to-SQL - універсальна BLL в патерні MVVM.
У 2007-му році, тобто 10 років тому, з'явилася досить універсальна BLL під назвою Linq-to-SQL. Ця бібліотека дає можливість дуже зручно користуватися даними (model), які піднімаються з рівня SQL. Це не єдиний такий засіб улаштування проміжного розумного рівня між програмою та моделью даних. Якщо подивитися на мою Класифікація засобів роботи з даними (нажаль так і не завершену до кінця) - то і "Доступ до даних за допомогою TableAdapter and SqlDataAdapter" і "Доступ до даних за допомогою TypedDataSet" мають всі ознаки повноцінного MVVM-патерну, тобто специфічного розумного рівня між простими даними та програмою, яка біндіться до цих даних.
4. MVVM у ASP.NET з використанням EF.
Я і досі вважаю Linq-to-SQL найбільш зручним засобом "вживання" даних, але у стеці технологій ASP.NET Variants of ASP NET Technology stack, але останній час набула поширення інша технологія - Entity Framework, яка взагалі була розроблена зі специфічною задумкою, у будь який момент без будь яких втрат змінити двигун даних, який зберігає дані на hard-діскі. Навіть не обов'язково на двигун, пов'язаний з SQL. Але мікрософт почав грати у якийсь свої ігри, щоб зменшит коштовність свойого SQL-серверу і підняти коштовніть своєї студії - і дурні піддались на цю рекламу і почали використовувати цю специфічну бібліотеку у будь-яких випадках, навіть коли проект буде завжди працювати на SQL-сервері і ніяких інших можливостей, виходячих за межи Linq-to-SQL у проекті не потрібно. Ну наприклад у Entity Framework існує якісь екзотичні можливості, яки дозволили молодим індусам знайти собі цікаву роботу, але ці можливості ніяк не корисні нікому іншому. Наприклад, якщо дані моделі мають назву Key та Data, то за допомогою мапера (який і є основною перевагою EntityFramework над Linq-to-SQL), дані в SQL можна зберігти з назвою Bred1 та Bred2, або навіть у одну колонку Bred.
Звичайно, що і сам по собі EF реалізує патерн MVVM, до того ж ще більше, ніж Linq-to-SQL, бо додає ще більш розумний та складний проміжний рівень між фрагментарними даними моделі та тим, що потрібно програмі для біндінга та відображення.
Якщо ми використовуємо EF, то для ASP.NET MVC є дуже цікавий додаток у патерні MVVM. Між справжньою моделью даних (особливо це корисно якщо вона зроблена як CODE First, бо в іншому випадку сам SQL-server зробить необхідні обмеження) - додається проміжний рівень. І цім проміжний рівнем можна дуже непогано керувати за допомогою атрибутів. Їх вичитує вбудоване середовище ASP.NET і обробляють клієнтськи скрипти у браузері. Тобто якщо написати, наприклад, що довжина текстової стрічки 100 символів, то про таке обмеження "автоматично" буде знати і браузер (з одного боку), і у справжню модель (з іншого боку) не попадуть стрічки більшої довжини.
5. MVVM у WPF.
Останній шаблон використання патерну MVVM, про який всі пишуть в інтернеті - це використання MVVM у WPF. Я не зовсім розумію цей підхід. По-перше MVVM існував задовго до утвороення самого мікрософту. Ніхто і ніколи напрямки не працював з даними моделей. Наприклад View у SQL-сервере існували це років за 20 до створення Мікрософту.
Подруге WPF з'явився у 2009-му році і перші роки викликав лише посмішки, особливо при роботі у браузері у вигляді Silverlight. Бо на тот момент вже на 99% кампутерів у світі працював Flash Player і іже років п'ять працювало поширення Flesh у вигляді Adobe Flex. Який взагалі працює по своєї ідеології набагато швидше, бо браузер бінарний код, який заздалегідь встановлений на кампутері, а не інтерпретує стрічка за стрічкой текстовий код JavaScript.
У цьому середовище працювали мільйони програмістів, студія для програмування та отладки там на базі Excipse і працює набагато краще Visual Studio. І взагалі один із найбільших розділів мого сайту )у якому я і досі програмую) саме програмування в Adobe Flex. А тут - здрасте - ось і мікрософт підрягнувся через 10 років і зробив якийсь свій власний клон WPF, який до того ж є конкурент їх власної технології Windows Forms.
Тому, коли я чую про якусь "новизну" мікрософтовських технологій, особливо у контексті WPF та MVVM - мене аж оторопь бере. Взагалі з голими моделями ніхто і ніде не працював, технолія MVVM існувала завжди, а коли мікрософт зробив клон Flex - і заявив про революційність свого клона Flex (особливо коли всі побачили всю її революційність - робота у тисячі разів повільгіше) - то залишилось лише плюватися в черговий раз на мікрософтовских дурнів, яких колихає зі стороні в сторону, незрозуміло чого вони взагалі шукають крім грошей та продажу своїх книжок. Але нас, програмістів, вони рахують повними дурнями - ми повинні вивчати якийсь дурниці, якийсь висери їх тупих індусів, та намагатися увесь цей бред використовувати. Замість існуючих, гарно працюючих технологий, до того ж все інсалированних на 99% процентів комп'ютерів у світі. І замість своїх власних (чудово працюючих) технологій Windows Forms.
Щодо приклада, який викладений Мікрософтом у Инет як підручник по MVVM - MVVM - Quick Guide. Я відтворив його сорсе-код і був здивований, що він навіть не компілюється. Потім я з'ясував, що це саме питання мають більш мільона програмістів.
Відповідь мене теж зацікавила - "цей код дуже старий, подивиться на новий".
Я подивився на новий код, опублікований у MSDN як шаблон - але кода там так і не побачив. Ось лінк на "нову версію" MVVM-шаблона кода від Microsoft. Мені здається, що цей лінк швидко загине в Инеті, тому я зробив його локальну копію. Ну це мабуть все, що потрібно зрозуміти про те, що мікрософтовскі індуси зрозуміли про MVVM.
В чому тут головна родзинка використання MVVM у WPF я так і не зрозумів, бо не код не працює і показати цю родзінку сами мікрософтовськи індуси не змогли.
А взагалі у автора MVVM-шаблону коду у WPF дуже велика проблема з будуванням EventHandler, він якось намагається будувати на Action'ах та Expression'ах. Це на 100% розбігається зі стандартним підходом, як ці хандлери взагалі будуються згідно документації - EventHandler(Of TEventArgs) Delegate.
6. Шаблон коду MVVM у WPF.
Якщо когось цікавить цей проєкт, перетрансльований на бейсік (це не автоматична процедура, тут потрібно думати), та з викушеною дурницею про комунікацію між View та ViewModel, яку навіть автору цього коду не вдалося пояснити, як воно повинно працювати, то цей приклад ви можете взяти собі звідси, з мойого сайту.
Мій проект побудований у локальному GIT'і і має шість поінтів (master, ViewModelLocator, Variant-binding-2, Variant-binding-1, DataTemplates-Resourses, Communication), тобто ви маєте можливість перехода від поінта до поінта в один клік.