Перейти к основному содержимому
Версия: 11.0.0

Архитектура

Важнейшим аспектов при создании кроссплатформенного приложения на Avalonia, является создание архитектуры, которая обеспечивает максимально возможное количество общего кода между платформами. Для создания хорошо структурированного приложения, советуем придерживаться фундаментальных принципов ООП:

  1. Инкапсуляция – Необходимо обеспечивать минимальный API для взаимодействия с классами и слоями архитектуры, скрывая детали реализации. На практике это означает, что объекты представлены "черными ящиками", и коду не нужно понимать, как их внутреннее устройство. Архитектурно, это означает реализацию паттернов на подобие Façade (рус: Фасад), которые способствуют упрощению API на более высоких слоях абстракций. Следовательно, код UI должен отвечать исключительно за отображение экранов и обработку пользовательского ввода, никогда напрямую не взаимодействуя с базами данных или другими операциями более низкого уровня.
  2. Разделение ответственности – Каждый компонент архитектуры или класса, должен иметь четкое назначение, выполнять только свои определенные задачи, а также предоставлять доступ к этой функциональности для других классов через API.
  3. Полиморфизм – Использование интерфейсов или абстрактных классов, позволяет писать реализации с учетом предлагаемых Avalonia специфичных функций конкретных платформ, которые потом взаимодействуют с основным кодом.

Результатом применения этих принципов, является приложение, основанное на реальных или абстрактных сущностях с различными логическими слоями.

Разделение кода на слои, упрощает понимание, тестирование и поддержку приложения. Рекомендуется как хранить код для каждого из уровней раздельно (разные каталоги или отдельные проекты), так и логически, используя пространства имен. Avalonia позволяет совместно использовать не только бизнес-логику, но и код UI для разных платформ, что уменьшает необходимость в нескольких проектах пользовательского интерфейса и еще больше расширяет возможности повторного использования кода.

Типичные слои приложения

В данном документе и тематических исследованиях, мы ссылаемся на следующие шесть слоев приложения:

  1. Слой данных – здесь происходит сохранение данных, вероятно, с помощью базы данных, таких как SQLite или LiteDB, но может быть реализовано и с помощью других механизмов, к примеру XML-файлов.
  2. Слой доступа к данным – Данный слой является оберткой над слоем данных, и обеспечивает доступ к операциям Create (рус: Создание), Read (рус: Чтение), Update (рус: Обновление) и Delete (рус: Удаление) (CRUD), без деталей реализации для вызывающей стороны. Например, этот слой может содержать SQL-запросы для базы данных, но коду, обращающемуся к нему, это знать необязательно.
  3. Слой бизнес-логики – Данный слой содержит определения бизнес-сущностей (Model) и бизнес-логику. Это основной кандидат для паттерна Facade (рус: Фасад).
  4. Слой доступа к сервисам – Данный слой используется для доступа к сетевым сервисам, начиная от сложных веб-сервисов (REST, GraphQL) и заканчивая простым извлечением данных и ресурсов с удаленных серверов. Он инкапсулирует сетевое поведения и предоставляет упрощенное API для работы на слоях приложения и UI.
  5. Слой приложения – Данный слой, обычно используется для платформозависимого или специфичного кода (обычно не используется повторно). Различие между данным слоем и слоем UI, становится более наглядным в Avalonia, поскольку код UI может быть общим для разных платформ.
  6. Слой пользовательского интерфейса (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, и логику в общем коде приложений, то данный паттерн может помочь в обработке исключений на разных платформах, а также использовать платформозависимые функции.

Async (рус: Асинхронность)

Не следует путать шаблон Async с одноименным ключевым словом. Шаблон используется, когда необходимо выполнять длительные задачи без зависания UI или текущей обработки. В простой форме, паттерн Async указывает, что длительные задачи должны запускаться в другом потоке (или аналогичной абстракции, к примеру Task), в то время как текущий поток продолжает обработку и ожидает ответа от фонового процесса. Обновление UI происходит при возврате данных или состояния. Это важно для поддержания отзывчивого UI в приложениях Avalonia.


Каждый из упомянутых выше паттернов, будет подробно изучен в рамках демонстрации наших тематических исследований. Для подробного понимания паттерном, рекомендуем ознакомиться со статьями Facade (рус: Фасад), Singleton (рус: Одиночка) и Provider (рус: Поставщик), а также с Design Patterns (рус: Паттернами проектирования) в целом.