GOOGLE ADS

понедельник, 2 мая 2022 г.

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

У меня есть проект ESP8266, запрограммированный в среде Arduino, который собирает данные из сети, а затем отображает их на дисплее. Устройство может быть построено с несколькими типами аппаратного обеспечения дисплея (eink, led, oled). Они устанавливаются во время компиляции с помощью #define. Однако есть также несколько различных типов данных и механизмов передачи данных, которые можно использовать. Некоторым требуется аппаратное обеспечение (LoRa TX/RX), и они включаются во время компиляции, но некоторые можно изменить во время выполнения в зависимости от пользовательских настроек (например, HTTP или MQTT).

Я уже использую фабричный шаблон проектирования для создания экземпляра объекта передачи данных во время выполнения, но по-прежнему использую флаги сборки времени компиляции, чтобы выбрать, какое оборудование дисплея использовать. У меня есть класс отображения, класс источника данных и класс конфигурации. Это сработало хорошо, но сейчас я достиг своего предела, когда я пытаюсь добавить функциональность сотовой связи.

Интересно, есть ли хороший шаблон проектирования/архитектурный дизайн, который будет способствовать такой гибкости без необходимости добавлять все больше и больше навязчивых операторов #ifdef по всему моему коду.

Приложена небольшая ментальная карта базовой схемы возможностей этого устройства.введите описание изображения здесь


Решение проблемы

Если вы хотите принять решение, какой алгоритм следует внедрить во время выполнения, вы можете попробовать использовать шаблон стратегии.

Как говорит Вики о шаблоне стратегии:

В компьютерном программировании шаблон стратегии (также известный как шаблон политики) представляет собой поведенческий шаблон проектирования программного обеспечения, который позволяет выбирать алгоритм во время выполнения. Вместо того, чтобы напрямую реализовывать один алгоритм, код получает инструкции во время выполнения о том, какой из семейства алгоритмов следует использовать.

Таким образом, вы можете прочитать свой файл конфигурации и выбрать, какой объект должен быть создан. Например, у вас много дисплеев:

public enum DisplayMark
{
Samsung, Sony, Dell
}

а затем вы должны создать базовый класс Display:

public abstract class Display 
{
public abstract string Show();
}

И тогда вам нужны конкретные реализации этого базового класса Display:

public class SamsungDisplay: Display
{
public override string Show()
{
return "I am Samsung";
}
}
public abstract class SonyDisplay: Display
{
public override string Show()
{
return "I am Sony";
}
}
public abstract class DellDisplay: Display
{
public override string Show()
{
return "I am Dell";
}
}

Все идет нормально. Теперь нам нужно что-то вроде маппера, который будет отвечать за отображение правильного экземпляра по выбранному дисплею из конфига:

public class DisplayFactory
{
public Dictionary<DisplayMark, Display> DisplayByMark { get; private set; }
= new Dictionary<DisplayMark, Display>
{
{ DisplayMark.Sony, new SonyDisplay()},
{ DisplayMark.Samsung, new SamsungDisplay()},
{ DisplayMark.Dell, new DellDisplay()},
};
}

а затем, когда вы будете знать, какой дисплей следует использовать из файла конфигурации, вы можете получить желаемый экземпляр:

public void UseDisplay(DisplayMark displayMark) 
{
DisplayFactory displayFactory = new DisplayFactory();
Display display = displayFactory.DisplayByMark[displayMark];
// Here you can use your desired display class
display.Show();
}

Комментариев нет:

Отправить комментарий

Laravel Datatable addColumn returns ID of one record only

Я пытаюсь использовать Yajra Datatable для интеграции DataTable на свой веб-сайт. Я смог отобразить таблицу, но столкнулся с проблемой. В по...