Архитектура
Важнейшим аспектов при создании кроссплатформенного приложения на Avalonia, является создание архитектуры, которая обеспечивает максимально возможное количество общего кода между платформами. Для создания хорошо структурированного приложения, советуем придерживаться фундаментальных принципов ООП:
- Инкапсуляция – Необходимо обеспечивать минимальный API для взаимодействия с классами и слоями архитектуры, скрывая детали реализации.
На практике это означает, что объекты представлены "черными ящиками", и коду не нужно понимать, как их внутреннее устройство.
Архитектурно, это означает реализацию паттернов на подобие
Façade (рус: Фасад)
, которые способствуют упрощению API на более высоких слоях абстракций. Следовательно, код UI должен отвечать исключительно за отображение экранов и обработку пользовательского ввода, никогда напрямую не взаимодействуя с базами данных или другими операциями более низкого уровня. - Разделение ответственности – Каждый компонент архитектуры или класса, должен иметь четкое назначение, выполнять только свои определенные задачи, а также предоставлять доступ к этой функциональности для других классов через API.
- Полиморфизм – Использование интерфейсов или абстрактных классов, позволяет писать реализации с учетом предлагаемых Avalonia специфичных функций конкретных платформ, которые потом взаимодействуют с основным кодом.
Результатом применения этих принципов, является приложение, основанное на реальных или абстрактных сущностях с различными логическими слоями.
Разделение кода на слои, упрощает понимание, тестирование и поддержку приложения. Рекомендуется как хранить код для каждого из уровней раздельно (разные каталоги или отдельные проекты), так и логически, используя пространства имен. Avalonia позволяет совместно использовать не только бизнес-логику, но и код UI для разных платформ, что уменьшает необходимость в нескольких проектах пользовательского интерфейса и еще больше расширяет возможности повторного использования кода.
Типичные слои приложения
В данном документе и тематических исследованиях, мы ссылаемся на следующие шесть слоев приложения:
- Слой данных – здесь происходит сохранение данных, вероятно, с помощью базы данных, таких как
SQLite
илиLiteDB
, но может быть реализовано и с помощью других механизмов, к примеру XML-файлов. - Слой доступа к данным – Данный слой является оберткой над слоем данных, и обеспечивает доступ к операциям
Create (рус: Создание)
,Read (рус: Чтение)
,Update (рус: Обновление)
иDelete (рус: Удаление)
(CRUD), без деталей реализации для вызывающей стороны. Например, этот слой может содержать SQL-запросы для базы данных, но коду, обращающемуся к нему, это знать необязательно. - Слой бизнес-логики – Данный слой содержит определения бизнес-сущностей (
Model
) и бизнес-логику. Это основной кандидат для паттернаFacade (рус: Фасад)
. - Слой доступа к сервисам – Данный слой используется для доступа к сетевым сервисам, начиная от сложных веб-сервисов (REST, GraphQL) и заканчивая простым извлечением данных и ресурсов с удаленных серверов. Он инкапсулирует сетевое поведения и предоставляет упрощенное API для работы на слоях приложения и UI.
- Слой приложения – Данный слой, обычно используется для платформозависимого или специфичного кода (обычно не используется повторно). Различие между данным слоем и слоем UI, становится более наглядным в Avalonia, поскольку код UI может быть общим для разных платформ.
- Слой пользовательского интерфейса (UI) – Данный слой содержит
views
, и управляющие имиview-models
. В отличии от традиционной архитектуры, где слой UI зависит от платформы, Avalonia позволяет совместно использовать данный слой на каждой поддерживаемой платформе.
Приложение может не содержать некоторые из слоев. Например, уровень доступа к сервисам может не присутствовать в приложении, которое не работает с сетевыми ресурсами. В более простых приложениях, можно объединить слой данных со слоем доступа данных, поскольку эти операции довольно просты. Avalonia по ддерживает возможность гибкого формирования архитектуры приложения, в соответствии с вашими потребностями, что обеспечивает высокую степень повторного использования кода на разных платформах.
Общие архитектурные паттерны
Паттерны - это хорошо зарекомендовавший себя подход, для стандартизации решения распространенных проблем. Есть несколько ключевых паттернов, которые стоит использовать при создании приложений на Avalonia.
Model, View, ViewModel (MVVM)
MVVM - это популярный, но в то же время часто неправильно используемый шаблон.
В основном, он используется при построении пользовательских интерфейсов и способствует разделению между фактическим определением экрана UI (View),
стоящей за ней логику (ViewModel
) и заполняющих его данных (Model
).
В нем, ViewModel
выступает посредником между View
и Model
.
И пусть Model
важна, но она является независимой, опциональной частью.
Поэтому суть паттерна сводится ко взаимосвязи между View
и ViewModel
.
Подробнее о паттерне MVVM, см. здесь.
Business Façade (рус: Фасад)
Данный паттерн обеспечивает упрощенную точку входа для сложных операций.
Например, в приложении отслеживаются задачи через класс TaskManager с методами GetAllTasks(), GetTask(TaskId),
SaveTask(task) и т.д.
Данный класс обеспечивает Faсade
для внутренних механизмов объектов tasks
.
Singleton (рус: Одиночка)
Паттерн Singleton
гарантирует, что может существовать только один единственный экземпляр указанного объекта.
Например, при использовании в приложениях SQLite
, обычно требуется только один экземпляр базы данных.
Provider (рус: Поставщик)
Паттерн впервые придумал Microsoft для решения проблемы повторного использования кода между приложениями на Silverlight
, WPF
и WinForms
.
Общий код описывается с помощью интерфейсов или абстрактных классов, а уже конкретные реализации пишутся под конкретную платформу,
и потом передаются при использовании кода.
Поскольку в Avalonia мы можем и UI, и логику в общем коде приложений, то данный паттерн может помочь в обработке исключений
на разных платформах, а также использовать платформозависимые функции.