Любой программный продукт можно оценить с точки зрения надежности, безопасности, удобства предлагаемых функций для пользователя. Эти показатели напрямую зависят от качества пользовательского интерфейса. Пользовательский интерфейс должен валидировать ввод данных, быть максимально простым в управлении, а также понятным для пользователя. Хорошо разработанный пользовательский интерфейс влияет на успех предлагаемого продукта на рынке программного обеспечения.
Интерфейс – комплекс программных и технических средств, посредством которых осуществляется взаимодействие оператора-человека с различными информационными системами в процессе их функционирования. В свою очередь, пользовательский интерфейс включает в себя компоненты, которые определяют характер данного взаимодействия. К ним относятся информационные поля, различные панели, диалоговое меню, сетки, списки и др. [1].
К особенностям пользовательского интерфейса можно отнести [2]:
– наличие графических средств управления программой;
– осуществление удобной навигации по функционалу программы;
– соответствие интерфейса бизнес-логики требуемой модели, а не бизнес-логика модели под интерфейс;
– обеспечение валидации входных данных и безопасности использования программы.
Материалы и методы исследования
В данном исследовании рассматриваются этапы разработки пользовательского интерфейса для программы, которая предоставляет услуги ветеринарной клиники и делает расчёт их стоимости. Данный проект реализует базовый функционал любой информационной системы. Разработанные для проекта алгоритмы поиска работают независимо от бизнес-логики приложения, следовательно, проект не теряет актуальности даже в долгосрочной перспективе.
Требования к программному продукту:
– независимость слоёв представления программы – реализовать приложение на архитектуре MVVM. Это предпочтительная архитектура для программного обеспечения, использующего функционал WPF;
– наличие базы данных с услугами;
– наличие алгоритма поиска по названию и категории услуги;
– реализация функции для расчета стоимости выбранных услуг.
Результаты исследования и их обсуждение
Первым этапом в реализации нашего программного продукта является проектирование. На этапе проектирования определяются требования к нашей программе и основные функции [3–5]. Диаграмма прецедентов представлена на рис. 1.
Рис. 1. Диаграмма прецедентов
Пользователь производит поиск интересующей его услуги посредством сортировки по названию или категории. После выбора услуг программа рассчитывает и показывает стоимость предоставляемых услуг.
Динамические аспекты поведения разрабатываемой системы описываются в виде диаграммы активностей [6]. На ней изображен алгоритм взаимодействия между пользователем и информационной системой. Пользователь с помощью инструмента поиска выбирает интересующие его услуги и узнаёт их суммарную стоимость (рис. 2).
Рис. 2. Диаграмма деятельности UML
На следующем этапе был разработан прототип интерфейса, который должен удовлетворять требованиям заказчика и быть максимально удобным для пользователей.
База данных включает две таблицы. Первая таблица «Услуги» содержит информацию о коде услуги, ее названии и типе. Во второй таблице хранится информация о стоимости услуг, так как для каждого животного она различна. Поскольку одна и та же услуга может относиться ко многим животным, то в зависимости от типа животного изменяется цена и другие параметры. На С# был создан шаблон подобной базы данных, которая позволяет изменять значения в процессе выполнения программы, то есть в самой программе таблицы будут работать как коллекции.
Программный продукт будет создаваться в MicrosoftVisualStudio 2019 на языке С#. В процессе разработки нам необходимо создать основные модели, которые будут представлять базу данных.
Листинг 1
Описание таблицы «Услуги»
public class Service : IModel
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Cost { get; set; }
public PetCategory PetCategory { get; set; }
static public implicit operator ServiceViewModel?(Service model) =>
new ServiceViewModel()
{
Id = model.Id,
Cost = model.Cost,
Name = model.Name,
PetCategory = model.PetCategory
};
}
Данный код описывает таблицу «Услуги». Каждое свойство класса Service указывает, какие поля будут включены в таблицу. Данный класс также композирует в себе указатель на экземпляр типа PetCategory, что означает, что данная таблица будет связана со второй таблицей.
Рис. 3. Прототип интерфейса
В листинге 2 объявляется класс PetCategory, который описывает таблицу категорий животных. Данный класс содержит в себе коллекцию экземпляров типа Service, что указывает на связь между таблицами «Один ко многим».
Листинг 2
Описание таблицы категорий животных
public class PetCategory : IModel
{
public int Id { get; set; }
public string Value { get; set; }
public List<Service> Services { get; set; }
public PetCategory()
{
Services = new List<Service>();
}
public static implicit operator PetCategoryViewModel?(PetCategory model) =>
new PetCategoryViewModel()
{
Id = model.Id,
Value = model.Value
};
}
Класс, представленный на листинге 3, VeterinaryDbContext, наследовавший класс DbContext, определяет настройки подключения к базе данных в методе OnConfiguring(), конфигурацию модели базы данных в методе OnModelCreating(), две дженерик-коллекции DbSet от классов PetCategory и Services, а также конструктор класса, реализующий DependencyInjection (встраиваемые зависимости), где в роли зависимости выступает конфигурация подключения к базе данных.
Листинг 3
Настройки подключения к базе данных
public class VeterinaryDbContext : DbContext
{
IConfiguration _configuration;
public DbSet<PetCategory> PetCategories { get; set; }
public DbSet<Service> Services { get; set; }
public VeterinaryDbContext() => Database.EnsureCreatedAsync();
public VeterinaryDbContext(DbContextOptions<VeterinaryDbContext> options) : base(options) => Database.EnsureCreatedAsync();
public VeterinaryDbContext(IConfiguration configuration)
{
_configuration = configuration;
Database.EnsureCreated();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Service>()
.ToTable("services_tbl")
.HasKey(key => key.Id);
modelBuilder.Entity<PetCategory>()
.ToTable("petCategories_tbl")
.HasKey(key => key.Id);
modelBuilder.Entity<PetCategory>()
.HasMany(s => s.Services)
.WithOne(p => p.PetCategory)
.HasForeignKey("FK_to_pet");
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) =>
optionsBuilder.UseSqlServer(_configuration["connectionString"]);
}
После введённой команды, в консоли диспетчера пакетов Add-Migration InitMigration с помощью библиотеки EntityFramework Core создаётся класс миграции, в котором описываются правила создания базы данных на хосте. Далее вводится команда Update-Database, начинается процесс миграции и создания базы данных на узле, указанном в строке конфигурации (в данном случае localhost).
Для создания интерфейса была выбрана технология WPF. Особенность данной технологии в преимущественном использовании разметки XAML. Для привязки данных к интерфейсу используется контекст данных. Контекст данных позволяет не заботиться об обновлении данных на стороне хранилища данных, загруженного в адресное пространство программы. Слой View (представление) связывается с ViewModel (модель представления), который в свою очередь обращается к абстрактным репозиториям (паттерн для обращения к данным, который представляет общий интерфейс для любой реализации связи с базой данных посредством полиморфизма). Конструктор инициализирует коллекции для отображения PetCategories и Services через реализации абстрактного репозитория, которые в свой конструктор для инициализации принимают экземпляр контекста базы данных.
В классе главного окна MainWindow инициализируется конфигурация и основной экземпляр класса ViewModel слоя VeterinaryClinicViewModel. Экземпляр ViewModel слоя присваивается к свойству DataContext для того, чтобы все элементы представления имели доступ к свойствам и коллекциям экземпляра VeterinaryClinicViewModel.
Результат разработки представлен на рис. 4.
Рис. 4. Интерфейс программного продукта
Пользователь может видеть список услуг ветеринарной клиники, осуществлять поиск и расчет нужной ему услуги.
Заключение
Программный продукт разработан и удовлетворяет всем требованиям заказчика. В дальнейшем планируется:
- оптимизировать поиск сервисов путем кеширования и повторного использования плана запроса к БД;
- осуществить переход на документоориентированную базу данных, поскольку данная сложность модели позволяет сделать этот переход, например MongoDB;
- оптимизировать алгоритм с помощью отказа от LINQ-запросов, которые относительно медленно работают со структурами данных. Если загружать данные с БД «порциями» (метод загрузки chunkcache) и эти данные сортировать оптимизированным алгоритмом, то скорость клиента возрастёт, а нагрузка на сервер снизится.