Мне интересно, есть ли шаблон, как отделить доменную логику класса от обязанностей пользовательского интерфейса объектов в доменном слое.
Пример:
// Domain classes
interface MachinePart
{
CalculateX(in, out)
// Where do we put these:
// Draw(Screen) ??
// ShowProperties(View) ??
// ...
}
class Assembly : MachinePart
{
CalculateX(in, out)
subParts
}
class Pipe : MachinePart
{
CalculateX(in, out)
length, diamater...
}
Существует приложение, которое вычисляет значение X для машин, собранных из множества деталей машин. Сборка загружается из файлового представления и является составной. Каждый конкретный класс детали хранит некоторые данные для реализации метода CalculateX(in,out)
для имитации поведения всей сборки. Приложение работает хорошо, но без графического интерфейса. Для повышения удобства использования необходимо разработать графический интерфейс поверх существующей реализации (изменения в существующем коде допускаются). Графический интерфейс должен отображать схематическое графическое представление сборки и предоставлять диалоговые окна для конкретных деталей для редактирования нескольких параметров.
Для достижения этих целей приложению необходимы новые функциональные возможности для каждой детали машины, чтобы нарисовать схематическое представление на экране, показать диалоговое окно свойств и другие вещи, не относящиеся к области машинного моделирования. Я могу придумать несколько разных решений для реализации Draw(Screen)
функциональности для каждой части, но я не доволен каждой из них.
Сначала я мог бы добавить Draw(Screen)
метод к интерфейсу MachinePart, но это смешало бы код домена с кодом пользовательского интерфейса, и мне пришлось добавить много функциональных возможностей для каждого класса детали машины, что делает мою модель домена трудной для чтения и трудно понять.
Другое «простое» решение - сделать все части доступными и внедрить пользовательский код в посетителей, но посетитель не принадлежит моим любимым шаблонам.
Я мог бы получить варианты пользовательского интерфейса из каждого класса детали машины, чтобы добавить туда реализацию UI, но мне пришлось проверить, подходит ли каждый класс детали для наследования и нужно ли быть осторожным с изменениями базовых классов.
В настоящее время мой любимый дизайн - создание параллельной составной иерархии, в которой каждый компонент хранит данные для определения машинной части, имеет реализацию для методов пользовательского интерфейса и фабричный метод, который создает экземпляры соответствующих классов домена, чтобы я мог "преобразовать" сборка пользовательского интерфейса для сборки домена. Но есть проблемы с возвратом из созданной доменной иерархии в иерархию пользовательского интерфейса для отображения результатов расчета, например, на чертеже (представьте, что некоторые детали сохраняют некоторые значения во время расчета, которые я хочу показать в схематическом представлении после симуляции).
Может быть, есть какие-то проверенные шаблоны для таких проблем?