Я работаю в области промышленной автоматизации. Это программное обеспечение будет контролировать несколько частей промышленного оборудования, используя последовательные соединения и протоколы, разработанные изготовителем каждого оборудования. Я создал объекты Value для общих параметров, таких как Distance, Voltage и т. Д., Однако каждая единица оборудования ожидает другого представления значения, а пользовательский интерфейс - еще один.Использование различных представлений объекта с одним значением
В качестве примера предположим, что мне нужно отрегулировать местоположение объекта на 1 см. Оборудование №1 ожидает, что расстояния будут в метрах, оборудование №2 ожидает, что расстояния будут находиться в микронах, а пользовательский интерфейс ожидает сантиметры. Я планирую использовать систему MKS, поэтому мой объект Value Value хранит количество в метрах.
Из книги Реализация домена Driven Design по Вона Вернон, мои ценностные объекты, кажется, как будто они должны удовлетворять характеристики стоимости объекта, как он описывает, а именно:
- Он измеряет, квантифицирует или описывает вещь в домене.
- Его можно сохранить неизменным.
- Он моделирует концептуальное целое, составляя связанные атрибуты как единое целое.
- Он полностью заменяется при изменении измерения или описания.
- Его можно сравнить с другими с помощью равенства ценности.
- Он поставляет коллаборационистов с побочным эффектом, свободной от поведения
Мысль 1: Добавить двенадцать общих метрических префиксов каждого класса Value Object.
public class Distance
{
private readonly double quantity; // in meters
public Distance(double distance)
{
quantity = distance;
}
public double AsCentimeters()
{
return quantity * 100;
}
}
Этот подход представляется неправильным, так как расчеты, основанные на приставках не изменится и будет дублироваться на нескольких объектах Value.
Мысль 2: Ввести перечисление с метрическими префиксами и базовый класс с расчетами.
public enum SIPrefix
{
None, Centi
};
public class SIUnitBase
{
protected readonly double quantity;
public double Value(SIPrefix prefix)
{
switch (prefix)
{
case SIPrefix.Centi:
return quantity * 100;
break;
default:
return quantity;
break;
}
}
}
public class Distance : SIUnitBase
{
public Distance(double distance)
{
quantity = distance;
}
}
// ... in code ...
Distance d = new Distance(1.0, SIPrefix.None);
Equipment.Move(d.Value(SIPrefix.Centi));
Этот подход кажется как подробным, так и подверженным ошибкам.
Мысль 3: Создайте набор методов расширения, чтобы добавить требуемую функциональность.
public static class DistanceExtensions
{
public static double AsCentimeters(this Distance distance)
{
return distance * 100;
}
}
Такой подход представляется почти столь же многословен, как мысли 1, но я мог бы осуществить только преобразования, мне нужно для конкретного применения.
Как смоделировать эту архитектуру, чтобы я мог предоставить каждому объекту домена и пользовательскому интерфейсу объект Value в ожидаемом представлении?
Поиск только вопросов по объекту с ценными данными выявил только one thread, аналогичный моей проблеме.
Я могу пойти с ** Мысль 3 **. Обратите внимание, что это просто проблема в том, как отображать результаты для пользователя, и он нуждается в еще одном параметре (единица используется) в диапазоне o know units (enum?). Пользовательский интерфейс должен просто отображать значение на основе сохраненного значения и единицы, используемой для этого свойства. – jean
** Мысль 4 ** - используйте F # [Единицы измерения] (http://fsharpforfunandprofit.com/posts/units-of-measure /), если язык переключения по-прежнему является опцией в этой точке – guillaume31
@ guillaume31 Не уверен, что стоит переключить язык для такой простой проблемы. – plalx