Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Декларативное программирование позволяет существенно повысить производительность труда программистов. В частности, предлагаемая Вашему вниманию библиотека DePro при программировании клиент-серверных приложений обеспечивает повышение производительности в 3 — 5 раз по сравнению с императивными языками такими, например, как java, kotlin.
Класс клиент – серверных приложений достаточно большой. К нему относятся такие типы приложений как: m-коммерция, Р2Р торговля, услуги, банки и финансы, путешествия, мессенджеры и соцсети, фитнес и здоровье, и т.п.
Такое ускорение объясняется тем, что в декларативном программировании описывать лишь “ЧТО нужно получить?”, а не “КАК это сделать?”.
Для иллюстрации различий между декларативным и императивным программированием рассмотрим следующий простой пример.
В activity изображенной на рисунке имеется fragment (обведен красной линией).
Разметка указанного фрагмента простая имеется лишь RecyclerView с id recycler. Разметка для элементов списка находится в файле item.xml. Данные находятся по адресу. Названия (id) элементов разметки совпадает с соответствующими названиями в данных, приходящих с сервера.
Программирование функционала этого фрагмента может основываться на различных технологиях (шаблонах). Используем одну из распространенных (MVP).
Для этого нам нужно создать следующие классы.
Item – описывает все переменные, которые приходят с сервера и соответствующие геттеры и сеттеры.
Adapter – наследник RecyclerView.Adapter. Ему в конструкторе передаются данные, полученные от сервера типа List. Также имеется три, в общем несложных, метода: getItemCount – указывает количество элементов списка; onCreateViewHolder – инфлатит View из файла item.xml и создает на его основе MyHolder; onBindViewHolder — читает нужный элемент в списке и заносит данные в MyHolder (в результате они отображаются на экране). Кроме того имеется класс MyHolder в котором описываются все переменные в которые будут заноситься данные.
Presenter — содержит метод чтения данных с сервера с использованием технологий RxJava и Retrofit. Он реально и обращается к серверу по заданному URL. Полученные данные с использованием интерфейса iView передаются во фрагмент (класс MyFragment).
iView – интерфейс для взаимодействия презентера и MyFragment.
MyFragment – наследник класса Fragment. В нем и происходит объединение взаимодействия всех остальных классов. В частности он создает пустой список данных (типа List.) и адаптер, которому передает этот список. Обращается к презентеру для ввода данных и, после их получения, обновляет список, после чего дает команду адаптеру отобразить новые данные.
В совокупности эти пять файлов содержат сто и более строк кода. Да, код не сложный и в основном рутинный. Однако количество кода — есть количество кода. При этом код для аналогичного фрагмента с другими данными будет отличаться только URL, ресурсом RecyclerView и item.xml.
Поэтому у некоторых программистов возникает фантастическая мечта — иметь метод, которому будут переданы только уникальные данные, а остальное он сам доделает. Например, такой:
recycler(URL, R.id.recycler, R.layout.item);
И вот именно эту фантастическую мечту и реализует библиотека декларативного программирования DePro. Например, для описания списка с использованием библиотеки нужно написать всего лишь одну строку:
component(TC.RECYCLER, model(URL), view(R.id.recycler, R.layout.item_news))
Здесь component – название метода для описания различных компонентов; TC.RECYCLER – тип компонента (в данном случае указывает на использование RecyclerView); model(URL) – указывает, что данные для компонента находятся по адресу указанному в URL; view указывает id recycler-а и лайаут с разметкой элементов списка.
Как видим, различие в количестве кода существенное.
Декларативное программирование с использованием библиотеки DePro сводится к описанию экранов и их компонентов. Ресурсы (строки, цвета, лайоуты, ...) формируются обычным образом.
Экраны могут реализовываться в виде активити или фрагмента. В простейшем случае активити задается следующим образом:
activity(имя активити, id лайоута связанного с этим активити)
Пример: activity(“splash”, R.layout.activity_splash)
Фрагмент задается аналогично.
Пример: fragment(“auth_phone”, R.layout.fragment_auth_phone)
Каждый экран содержит несколько компонентов. Компоненты характеризуется способом обработки и отображения данных и реализует шаблон MVP.
Все компоненты описываются унифицировано:
.component(TYPE, model(...), view(...), navigator(...))
Здесь TYPE — тип компонента, может принимать значения SPINNER, DRAWER, RECYCLER, MENU, MAP, PAGER и т.д. Параметры метода model(...) описывают источник данных. В частности, как указывалось выше, в нем может содержаться URL. Параметры метода view(...) задают представление, связанное с компонентом. В методе navigator(...) описывается реакция на действия пользователя. Например, запись navigator(start(R.id.video, YOUTUBE))
означает, что при тапе на элемент R.id.video будет вызван экран с именем YOUTUBE. В navigator-е можно указывать произвольное количество действий.
Таким образом, описание экранов представляет собой описание их компонентов:
activity(String name, int layoutId)
.component(TYPE, model(...), view(...), navigator(...))
. . .
.component(TYPE, model(...), view(...), navigator(...));
По факту описание отдельного экрана в зависимости от количества содержащихся в нем компонентов занимает в среднем 5 — 10 строк кода.
Параллельная разработка нескольких коммерческих проектов по традиционной технологии и с использованием библиотеки DePro позволило сделать следующие выводы:
- Количество java кода (SLOC) с использованием библиотеки в 40-50 раз меньше чем при традиционном подходе.
- Время описания одного экрана (без учета разработки XML — файлов) составляет 15 — 20 мин.
- Трудоемкость труда программистов (с учетом разработки XML — файлов) с использованием библиотеки в 3 — 5 раз меньше чем по традиционной технологии.
- Время тестирования в 2 — 3 раза меньше.
Подробное описание библиотеки с примерами приведено по адресу. С примерами использования библиотеки можно ознакомиться на Github.
В следующей статье опишем полный цикл разработки приложения с использованием библиотеки DePro.