Настраиваемые свойства отображения для моделей доменов - PullRequest
0 голосов
/ 08 ноября 2018

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

Здесь бизнес-логика модели предметной области проста: вычисляется «масштабированное» значение из входных данных, коэффициента усиления и смещения.

//Domain Model
public class Transducer
{
    //Name is the ID
    public string Name { get; set; }
    public double Gain { get; set; }
    public double Offset { get; set; }
    public double RawValue { get; set; }

    public double ScaledValue { get; private set; }


    public double CalculateScaledValue(double RawValue)
    {
        ScaledValue = (Gain * RawValue) + Offset;
        return ScaledValue;
    }

}

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

//implementation of execution of business logic and persistance would go in the implentation, details left out for this example
public interface ITransducerUseCase
{
    IEnumerable<string> GetAllTransducerNames();
    void AddNewTransducer(string Name, double Gain, double Offset);
    void SetGain(string Name, double Gain);
    void SetOffset(string Name, double Offset);
    void SetRawValue(string Name, double Raw);

    double GetScaledValue(string Name);

}

Вариант использования используется контроллером для координации вариантов использования с представлением или другим контроллером. Этот специальный контроллер позволяет просматривать все имена преобразователей и может изменять их свойство Gain.

public class Controller
{
    ITransducerUseCase _TransducerUseCase;

    //these are sent to the view to be displayed
    public Dictionary<string, double> _transducerScaledValues = new Dictionary<string, double>();

    public Controller(ITransducerUseCase TransducerUseCase)
    {
        _TransducerUseCase = TransducerUseCase;
        //Get all the names and populate the dictionary to display.
        foreach (var transducerName in _TransducerUseCase.GetAllTransducerNames())
            _transducerScaledValues.Add(transducerName, _TransducerUseCase.GetScaledValue(transducerName));
    }

    //bound to the view
    public string SelectedName { get; set; }
    //bound to the view, a property for setting a new gain value
    public double Gain { get; set; }

    public void OnButtonClick()
    {
        //update the gain
        _TransducerUseCase.ChangeGain(SelectedName, Gain);
        //get the new scaled value            
        _transducerScaledValues[SelectedName] = _TransducerUseCase.GetScaledValue("PumpPressure");

    }
}

Это леса для этого вопроса. Вот новое требование:

  • Мы хотим иметь настройки конфигурации уровня приложения для «количество десятичных знаков», которое отображается для ScaledValue из Transducer на основе идентификации. Так что преобразователь с идентификатором «PumpPressure» может иметь значение, отличное от DisplayRounding преобразователь с названием «PumpTemperamer».

  • Этот параметр должен быть применим ко всей программе (в любое время значение используйте эту настройку). Эту настройку также можно использовать, если ScaledValue когда-либо был зарегистрирован в файл, так что это сквозная деловая потребность.

Решения, о которых я подумал: Помещение свойства в модель предметной области и возвращение его через слои в представление. Это не выглядит логичным, поскольку свойство DisplayRounding не имеет никакого отношения к бизнес-логике.

public class Transducer
{
    //This seems like an SRP violation
    public int DisplayRounding { get; set; }

    //Name is the ID
    public string Name { get; set; }
    public double Gain { get; set; }
    public double Offset { get; set; }

    public double ScaledValue { get; private set; }


    public double CalculateScaledValue(double RawValue)
    {
        ScaledValue = (Gain * RawValue) + Offset;
        return ScaledValue;
    }

}

Если не там, то где?

Можем ли мы поместить ее в отдельную модель предметной области без какой-либо бизнес-логики? Постоянство может управляться тем же классом вариантов использования или отдельным классом.

public class TransducerDisplaySettings
{
    public int Rounding { get; set; }
    //plus other related properties
} 

Плюсы: он лучше разделяет проблемы, чем одна объединенная модель.

Минусы: модель не имеет бизнес-логики, это нормально?


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

Плюсы: нет моделей домена без бизнес-логики

Минусы: Возможно, будет привязан к конкретной структуре?


Есть ли еще плюсы / минусы, по которым я скучаю? Один подход явно лучше другого? Есть ли подход, который я полностью пропустил? Спасибо!

Ответы [ 2 ]

0 голосов
/ 10 февраля 2019

Главное решение, которое вам нужно будет принять, заключается в том, является ли округление отображения аспектом бизнес-логики ваших приложений или «просто аспектом отображения».

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

В случае, если вы рассматриваете это просто как аспект «представления значений пользователю» (что не относится к бизнес-правилам), он должен храниться в отдельном хранилище или службе изатем применяется "ведущий".

0 голосов
/ 08 ноября 2018
[table("NameTable")]
public class Transducer
{
    //Name is the ID
    [Key] //is Key from table
    public string Name { get; set; }
    public double Gain { get; set; }
    public double Offset { get; set; }
    public double RawValue { get; set; }

    public double ScaledValue { get; private set; }


    public double CalculateScaledValue(double RawValue)
    {
        ScaledValue = (Gain * RawValue) + Offset;
        return ScaledValue;
    }

}
...