Поставете вашия контролер на изглед на диета с разработка на уеб сайт с код MVVM, компютърни игри

- Споделям във Фейсбук
- Tweet
- Споделете в Google+
- Публикувайте в Tumblr
- Закачете го
- Добави към Pocket
- Изпратете имейл
В последния си пост от тази поредица писах за модела Model-View-Controller и някои от неговите несъвършенства. Въпреки очевидните предимства, които MVC носи за разработването на софтуер, той не отговаря на големи или сложни приложения на какао.
Това обаче не е новина. През годините се появиха няколко архитектурни модела, които се насочват към недостатъците в модела Model-View-Controller. Може би сте чували за това MVP, Model-View-Presenter и MVVM, Например Model-View-ViewModel. Тези модели изглеждат и се чувстват подобни на модела Model-View-Controller, но те също така разглеждат някои от проблемите, които моделът View-Controller представя.
1. Защо Model-View-ViewModel
Бях използвал модела Model-View-Controller години наред, преди случайно да попадна на модела Model-View-ViewModel Шаблон. Не е изненадващо, че MVVM е потомък на общността на какаото, тъй като произходът му датира от Microsoft. Моделът на MVVM обаче е пренесен в Какао и е адаптиран към изискванията и нуждите на какаовото скеле и наскоро придоби известност в общността на какаото.
Най-атрактивно е как MVVM се чувства като подобрена версия на модела Model-View-Controller. Това означава, че не изисква драматична промяна в мисленето. След като разберете основите на шаблона, той е доста лесен за изпълнение, не по-труден от модела на модел-изглед-контролер.
2. Поставете View Controller на диета
В предишната публикация писах, че контролерите в типично приложение за какао са малко по-различни от контролерите, които Reenskaug е дефинирал в оригиналния модел на MVC. Например в iOS контролер на изглед контролира изгледа. Вашата единствена отговорност е да попълните изгледа, който управлява, и да отговорите на взаимодействието на потребителя. Това обаче не е единствената работа на View Controllers в повечето приложения на iOS?
Моделът MVVM въвежда четвърти компонент в сместа, Покажи модел, което помага за префокусиране на контролера на изгледа. Това става чрез поемане на някои от отговорностите на контролера на изгледа. Разгледайте следната диаграма, за да разберете по-добре как View Model се вписва в модела Model-View-ViewModel.

Както показва диаграмата, контролерът за изглед вече не притежава модела. Моделът на изглед притежава модела и контролерът на изгледа иска от модела на изгледа данните да бъдат показани.
Това е важна разлика от модела модел-изглед-контролер. Контролерът за изглед няма пряк достъп до модела. Моделът на изглед дава на контролера на изгледа данните, които трябва да покаже в неговия изглед.
Връзката между View Controller и неговия изглед остава непроменена. Това е важно, тъй като контролерът на изгледа може да се съсредоточи върху попълването на своя изглед и да обработи взаимодействието на потребителя. За това е разработен View Controller.
Резултатът е доста драматичен. Контролерът на изглед е поставен на диета и много отговорности са прехвърлени към модела на изглед. В крайна сметка вече няма контролер на изглед, който да обхваща стотици или дори хиляди редове код.
3. Отговорности на визуалния модел
Сигурно се чудите как моделът за гледане се вписва в по-голямата картина. Какви са задачите на визуалния модел? Как е връзката с контролера на изгледа? А какво да кажем за модела?
Диаграмата, която ви показах по-рано, ни дава някои насоки. Нека започнем с модела. Моделът вече не принадлежи на View Controller. Изгледният модел притежава модела и действа като прокси за контролера на изгледа. Когато контролерът на изглед се нуждае от елемент от данните от своя модел на изглед, той иска своя модел за сурови данни и го форматира, така че контролерът на изгледа да може да го използва незабавно в своя изглед. Контролерът на изглед не е отговорен за манипулиране и форматиране на данни.
Диаграмата показва също, че моделът е собственост на модела на изглед, а не на контролера на изгледа. Трябва също да се отбележи, че моделът Model-View-ViewModel отчита тясната връзка между контролера за изглед и неговия изглед, който е характерен за приложенията на какао. Поради това MVVM се чувства като естествен избор за приложения с какао.
4. Пример
Тъй като моделът Model-View-ViewModel не е включен в какаото, няма строги правила за прилагане на шаблона. За съжаление, това се обърква от много разработчици. За да изясня няколко неща, искам да ви покажа основен пример за приложение, което използва шаблона MVVM. Създаваме много просто приложение, което извлича данни за времето за предварително дефинирано място от API на Dark Sky и показва на потребителя текущата температура.
Стъпка 1: настройка на проекта
Стартирайте Xcode и създайте нов проект, базиран на Приложение с един изглед Шаблон. Използвам Xcode 8 и Swift 3 за този урок.

Назовете проекта MVVM, и сложи език да се Бърз и Устройства да се iPhone.

Стъпка 2: Създайте модел на изглед
В типично приложение за какао, изпълняващо модела Model-View-Controller, View Controller ще направи мрежовата заявка. Можете да използвате мениджър, за да направите мрежовата заявка, но контролерът за изглед все пак ще знае откъде идват данните за времето. По-важното е, че той получава суровите данни и трябва да ги форматира, преди да бъдат показани на потребителя. Това не е подходът, който използваме, когато приемаме модела Model-View-ViewModel.
Нека създадем модел на изглед. Създайте нов файл Swift, дайте му име WeatherViewViewModel.swift, и дефинирайте клас, наречен WeatherViewViewModel .

Идеята е проста. Контролерът за изглед пита модела на изгледа за текущата температура за предварително дефинирано място. Тъй като изгледният модел изпраща мрежова заявка към API на Dark Sky, методът приема заключване, което се извиква, когато изгледният модел има данни за контролера на изгледа. Тези данни могат да бъдат текущата температура, но могат да бъдат и съобщение за грешка. Ето как изглежда методът StromTemperatur (завършване:) В на модела на изглед. Ще попълним подробности след няколко минути.
Декларираме псевдоним на тип и дефинираме метод, StromTemperature (Завършване:), който приема затваряне на CurrentTemperatureCompletion .В тип
Не е трудно да се приложи, ако сте запознати с работата в мрежа и URLSession API. Погледнете кода по-долу и забележете, че използвах API за куршуми, за да поддържам всичко хубаво и чисто.
Единственият код, който все още не съм ви показал, е прилагането на температурата (чрез:) метод. В този метод извличаме текущата температура от реакцията на Dark Sky.
В производствено приложение бих избрал по-надеждно решение за анализ на отговора, напр. Б. ObjectMapper или Unbox.
Стъпка 3: Интегрирайте модела на изглед
Вече можем да използваме модела на изглед в контролера на изгледа. Ще създадем свойство за модела на изглед и също така ще дефинираме три изхода за потребителския интерфейс.
Обърнете внимание, че контролерът за изглед е собственик на модела за изглед. В този пример контролерът на изглед също е отговорен за създаването на екземпляр на своя модел на изглед. Като цяло предпочитам да инжектирам модела на изглед в контролера на изгледа, но нека просто го направим засега.
В изгледа Controller viewDidLoad () методът извикваме помощен метод, fetchWeatherData () .
В fetchWeatherData () питаме модела на изглед за текущата температура. Преди да направим запитване за температурата, ние скриваме етикета и бутона и показваме индикатора за активност. При затварянето преминаваме към fetchWeatherData (Завършване:), Актуализираме потребителския интерфейс, като попълним етикета за температура и скриваме индикатора за активност.
Бутонът е свързан с действие fetchWeatherData (_:), в което също извикваме помощния метод fetchWeatherData (). Както можете да видите, помощният метод ни помага да избегнем дублирането на код.
Стъпка 4: Създайте потребителски интерфейс
Последната част от пъзела е създаването на потребителски интерфейс за примерното приложение. Отворете Дънна платка и добавете етикет и бутон към вертикален изглед на стека. Индикатор за активност се добавя в горната част на изгледа на стека, центриран вертикално и хоризонтално.

Не забравяйте да свържете изходите и действието, което дефинирахме в класа ViewController!
Сега изградете и стартирайте приложението, за да опитате. Не забравяйте, че ви е необходим ключ за API на Dark Sky, за да работи приложението. Можете да се регистрирате за безплатен акаунт на уебсайта на Dark Sky.
5. Какви са ползите?
Въпреки че сме преместили само няколко незначителни неща в модела на изглед, може би се чудите защо това е необходимо. Какво спечелихме? Защо трябва да добавите този допълнителен слой сложност?
Най-очевидното предимство е, че контролерът на изгледа е по-слаб и по-фокусиран върху управлението на неговия изглед. Това е основната задача на контролера на изгледи: управление на неговия изглед.
Но има и по-фина полза. Тъй като View Controller не носи отговорност за получаване на данни за времето от API на Dark Sky, той не знае подробностите за тази задача. Данните за времето могат да идват от друга метеорологична служба или от кеширан отговор. Контролерът на изглед не би и не трябва да знае.
Тестването също подобрява много. Известно е, че контролерите на изгледа са трудни за тестване поради близката им връзка с равнината на изгледа. Премествайки част от бизнес логиката в модела на изглед, ние веднага подобряваме проверимостта на проекта. Тестването на модели на изглед е изненадващо лесно, тъй като те нямат връзка към нивото на изглед на приложението.
Заключение
Моделът Model-View-ViewModel е основен напредък в дизайна на приложенията за какао. Изгледните контролери не са толкова обширни, изгледните модели са по-лесни за сглобяване и тестване и това улеснява работата с вашия проект.
В тази кратка поредица сме само надраскали повърхността. Има много повече неща за писане за модела Model-View-ViewModel. През годините се превърна в един от любимите ми модели и затова непрекъснато говоря и пиша за него. Опитайте и ми кажете какво мислите!
Междувременно можете да разгледате някои от другите ни публикации за разработването на приложения Swift и iOS.