Часть 2: Многоуровневая архитектура

(Часть1)

Пока я изучал курс LS185 в учебном плане Launch School, у меня появилась идея собственного веб-приложения — трекера привычек, которое позволило бы разбирать паттерны поведения на мельчайшие составные части. Я придумал первоначальную идею после того, как ознакомился с книгой Атомные привычки Джеймса Клира и использовал приложение WorkFlowy.

Отличие моего приложения от других линейных трекеров привычек, таких как HabitBull, или простого вычеркивания календарных дней, заключалось в том, что я собирался сделать *фрактальный* способ визуализации поведения (концепция кратко объяснена здесь Средний писатель).

У меня также были идеи об изменении базовой архитектуры на децентрализованную сеть сообщества, позволяющую учиться на привычках друг друга, но с суверенитетом личных данных. Открытие Holochain — нового децентрализованного фреймворка и инфраструктуры облачных вычислений — с самого начала привело меня к серьезному кодированию бэкенда. Для меня это было бы долгосрочной целью — сделать свое первое приложение Holochain. Но сначала я бы подробно изучил архитектуру клиент-сервер и сделал одностраничное приложение.

Учиться с первой попытки

Версия локального хранилища, которую я уже сделал, была довольно тесно связана с приложением Todo list, которому я следовал вместе с учебным планом LS. Нам посоветовали поэкспериментировать и сделать свои собственные простые приложения таким образом.

Я показал приложение в его прототипе однокурснику Стиву. У него было больше опыта работы с JavaScript, чем у меня, и он видел некоторые ограничения моего дизайна. Я несколько привязался к использованию компонента jQuery Swiper, и это заставляло меня писать много сложного в сопровождении кода.

Теперь я начал узнавать, что есть инструменты почти для любой работы, и, к счастью, Стив указал мне на библиотеку D3js. Я все еще был новичком в модульном проектировании и не использовал ничего, кроме jQuery, в своем подходе к управлению DOM.

Планирование нового пользовательского интерфейса

Я потратил некоторое время на то, чтобы разобраться с основами объединения данных D3, различными макетами и тем, как я могу визуализировать свою фрактальную структуру в браузере. При разработке визуализаций внешнего интерфейса:
1. Мне нужно было включить d3-zoom.
2. Наиболее близким макетом, который я мог представить для работы со своей структурой данных, была масштабируемая диаграмма сосулек, где всего 3 уровня. отображаются в любой точке.
3. Это основано на иерархической структуре данных, поэтому мне нужно было изучить, как d3 работает с иерархическими данными.
4. Попытаться загрузить полное дерево данных для каждого пользователя сразу вызовет проблемы с рендерингом, как только дерево достигнет определенного размера.
5. Вместо этого я мог бы заполнить объединение данных уровнем иерархии, который я хотел визуализировать в любой момент (поддерево). и запрашивать края моих данных (листья отображаемого в данный момент дерева) на конкретном уровне, который я просматривал. Идея о том, что данные разбиения на страницы извлекаются с приращением, казалась наиболее близким приближением.

Базовые принципы SOLID

В период между первым проектом и наброском описанного выше пути к MVP я также изучал реляционные базы данных с помощью PostgreSQL. Я всегда знал, что локальное хранилище не годится ни для чего, кроме личного прототипа интерфейса и концепции, но теперь передо мной встала задача выбора постоянного хранилища данных. Моя главная задача в Части 1 заключалась в том, как разделить заботы — как сказал дядя Боб — так, чтобы отсрочить принятие окончательного решения как можно дольше.

Мне потребовалось немного времени, чтобы разобраться с внедрением зависимостей и инверсией управления, а также с разделением ответственности за объектно-реляционное сопоставление. Я провел время, изучая библиотеки dry-rb и их использование. Библиотеки облегчают реализацию идеи дяди Боба!

Выбор стека

Я использовал стартер для всплеска, просто чтобы изучить многоуровневую структуру SPA.

Я читал о философии рабочего процесса разработки «Build First», объединении активов в JS и модульном дизайне. Все это должно быть включено в будущем. Я начал узнавать об использовании реактивных JS-фреймворков, но, не желая слишком сильно отклоняться от философии «освоения основ», принятой в Launch School, я решил не изучать какой-либо крупный фреймворк, а взял MithrilJS (он легкий и с ним легко начать работу).

БЭКЭНД:
- Sinatra для маршрутизации
- Sequel и ROM-rb для ORM
- dry-rb, набор современных библиотек Ruby, для организации кода и DI
- PostgreSQL

FRONTEND:
- MithrilJS
- D3 для визуализации
- Axios для запросов к серверной части
- Webpack

Я бы настроил оба слоя как отдельные контейнеры Docker и разрешил непрерывную интеграцию/разработку с действиями Github, отправляя новые версии образов в Docker Hub при каждом нажатии на основную ветку git.

Что я придумал

Я сделал веб-API для хранения и обслуживания иерархически структурированных (JSON) сериализованных данных о привычках. Выбор дизайна, который я выбрал, обеспечивает быстрое взаимодействие между прикладным уровнем и уровнем сохраняемости данных, а также возможность переключать Источник абсолютной истины с базы данных на файл сериализованных данных, просто передав строку запроса `?demo=true` внешнему интерфейсу. Мне удалось сделать это, сохранив при этом большую часть основных функций приложения (по сравнению с тем, когда оно использовало слой сохраняемости PostgreSQL).

Моя первоначальная цель состояла в том, чтобы продемонстрировать идею дяди Боба о SOLID-дизайне, позволяющую сделать базу данных «деталью реализации». Я надеялся, что это позволит адаптироваться к децентрализованной архитектуре в будущем.

Библиотека ROM-rb (Ruby Object Mapper) с ее адаптером YAML сыграла решающую роль в этом, но адаптер не позволяет записывать в файлы. Это означало, что я мог сделать только версию «только для чтения», которая не сохраняла бы изменения в сериализованных данных дольше, чем сеанс. В демонстрационных целях это нормально, и оставляет возможность легко переключить обратно уровень сохраняемости в базу данных после того, как поэкспериментирует со структурой извлеченных из Интернета данных: адаптер в истинном смысле. Это, в свою очередь, сделает приложение более доступным, поскольку люди смогут «импортировать» структуры привычек из Интернета, а затем делать их своими, сохраняя их в базе данных.

РЕДАКТИРОВАТЬ: после переноса пользовательского интерфейса на React демонстрация этой функции больше не работает. Вместо этого я реализовал демонстрацию пользовательского интерфейса с готовыми шаблонами, с которыми можно поиграть.

Области для улучшения

Из-за того, что в то время мне еще предстояло познакомиться с React и Redux, я не придумал целостного шаблона управления состоянием для интерфейса. К тому времени, когда я использовал несколько уровней состояния компонентов, это стало реальной проблемой. Позже я узнал, что паттерн Мейоз очень хорошо сочетался бы с облегченным подходом MithrilJS, и это хорошее введение в паттерны Redux.

С тех пор, как я начал создавать версию Holochain-backend, я с самого начала сосредоточился на Redux и ожидаю переписать многие компоненты внешнего интерфейса для работы с React, что сделает фрактальное представление намного более отзывчивым и сгладит ошибки управления состоянием, упомянутые выше.

Сколько из моих 5 очков пользовательского интерфейса мне удалось набрать? В настоящее время это масштабируемая древовидная диаграмма без буферизованного потока данных типа «разбивка на страницы». Версия React должна поразить все 5, чтобы сделать визуализацию фрактальной.

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

Узнайте в части 3!