DroidScript
DroidScript
разработка мобильных приложений

Шаблон проектирования MVC

Thunkable X  
12.01.2020

Существует множество подходов к разработке приложений. А раз так, то, очевидно, среди всего их множества есть те, которые позволяют вести проектирование приложений, отлаживать их и поддерживать проще, быстрее и эффективнее. Для этого как раз и предназначена рассматриваемая концепция проектирования. Интересно то, что во многих случаях пользователи применяют некоторые аспекты данной концепции, даже не подозревая об этом. Но гораздо большего эффекта можно добиться в том случае, когда разработка ведётся не на интуитивном уровне, а осмысленно и на на основе знаний.

В основе шаблона проектирования MVC лежит простая и всем хорошо известная идея разделения обязанностей и контроля за тем, кто за что отвечает и чем для этого должен заниматься. Если такого разделения и контроля за ним нет, то с большой степенью вероятности возникнет бардак, в котором сложно будет что-то понять. Аналогичная ситуация возникнет и с проектом, если весь процесс его создания, а затем поддержки готового приложения ведётся как попало.

MVC - (Model-View-Controller "модель-вид-контроллер") - это концепция разделения данных приложения, логики его работы и интерфейса на три компонента, редактирование которых может происходит независимым друг от друга образом. Такое разделение может производиться при помощи файлов: создаются три директории для хранения файлов моделей, контроллеров и видов с ограниченным доступом в идеальном случае. Тогда дизайнер не сможет отредактировать файл ядра приложения, а пользователь базы данных - изменить фон и положение кнопок интерфейса. Применительно к Thunkable X файловое разделение осуществить никак не получится, но его можно осуществить при помощи функций и экранов, которые существуют, но не отображаются в работающем приложении. Такие экраны далее будут называться модулями.

Что относится к модели, виду и контроллеру?

К моделям относятся компоненты для работы с данными, которые не имеют видимого представления на экране приложения - Local DB, Local Storage, SpreadSheet, Realtie DB. Эти компоненты являются глобальными, и им не нужен отдельный экран. Но для реализации пользовательской модели, функциональность которой выходит за рамки данных компонентов, потребуется экран или модуль.

К видам относятся элементы интерфейса, имеющие видимое представление на экране работающего приложения - Button, Lavel, Text Input, List Viewer, Web Viewer и др.

Контроллёры - это программная логика, посредством которой происходит связь моделей с видами. То есть, данные с элементами интерфейса взаимодействуют не напрямую, а только через контроллер.

Рассмотрим это на примере.

Плохое проектирование

Здесь конкретный компонент вида (кнопка Button1) взаимодействует с конкретным компонентом модели (tabData) непосредственным образом, что приводит к появлению жесткого частного решения. А что делать, если нужно сохранять данные и при нажатии на другие кнопки? Неопытный пользователь просто скопирует показанные блок нужное количество раз, изменит в них название кнопки и получит дублирующиеся блоки, что сразу усложнит всю дальнейшую работу с ними. Более опытный пользователь создаст функцию, как в примере ниже.

Плохое проектирование

Функция saveData как раз и является контроллером, посредством которого виды взаимодействуют с моделью. Но показанный пример также далёк от идеала, потому что в функции вида опять происходит непосредственная работа с данными - используются блоки с литералами "Сообщение 1" и "Сообщение 2". А как быть, если эти сообщения нужно выводить на разных языках в зависимости от выбора языка интерфейса пользователями? Придётся городить блоки с многочисленными и ненужными проверками. Количество блоков будет расти как снежный ком, в котором разобраться самостоятельно многие пользователи уже не смогут.

Корни возникновения данной ситуации лежат, во-первых, в недостаточно качественной подготовке к проектированию, когда пользователь для простоты и скорости пытается создавать приложение "на лету", не имея даже наброска того, что он собирается создать, и, во-вторых, замене процесса обдумывания общего решения созданием блоков для быстрого получения частных реализаций. Это похоже на то, как при сборке лего-модели из головы начать склеивать детали друг с другом. Кто-то будет делать так? Нет, но при разработке приложений это встречается повсеместно из-за стойкого убеждения в том, что при помощи компьютера можно всё легко и быстро исправить.

Ниже показан пример решения задачи с учётом MVC

MVC

Здесь нет ни одного блока с текстом. Он находится в компоненте модели Local DB, куда копируются из Excel (где намного проще работать с табличными данными). Если в исходных данных была обнаружена ошибка, то разработчику не нужно просматривать десятки экранов для того, чтобы найти глобальную переменную, данные в которой нужно исправить. Он открывает Excel, производи правку и копирует данные в Local DB. Если на каком-то экране появится текст, то это сразу укажет на ошибку проектирования, которая внутри себя может скрывать и логическую ошибку.

Элементы интерфейса взаимодействуют с данными посредством функций контроллера - showAlert и setText. Если вместо системного диалога Alert мы захотим использовать свой диалог, то это никак не повлияет на содержимое блоков видов и ничего не нужно будет менять в блоках обработчиков событий кнопки и области просмотра списка. Если на экране появятся новые компоненты, то это никак не повлияет на содержимое функции showAlert, но приведёт к необходимости дополнить модель и функцию контроллёра setText.

При получении данных о пользователя они также проходят через контроллер, в котором происходит проверка данных на корректность. Если этго не делать, то пользователь случайно или специально введёт некорректные данные, которые сразу запишутся в базу, что не только приведёт к ошибке в данных,но и может слмать приложение, если данные также без проверки на корректность будут испоьзованы при выполнении операции над ними.

В Thunkable X нет возможности обращаться к компонентам, расположенным на других экранах. Значит, функции контроллёра должны располагаться вместе с блоками вида или придётся использовать межэкранный вызов функций при помощи таймера для работы с видами.

Если функции компонентов расположены на одном экране, то стоит подумать об их пространственном разделении, например, функции видов располагаются слева, а контроллёров справа или первые вверху, а вторые внизу.

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

Thunkable X  
© 2016-2020  Александр Страшко