2015-07-29 3 views
1

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

Моего первое направление (передать данные в конструктор):

public class MyClass 
{ 
    private readonly ICalculator _calculator; 
    private readonly MyClassDataPOCO _data; 

    public MyClass(ICalculator _calculator, MyClassDataPOCO data) 
    { 
     this._calculator = _calculator; 
     _data = data 

Это не работает хорошо, потому что тогда ваши контейнеры МОК не могут автоматически инициализировать классы.

Второе направление (передать данные в эксплуатацию):

public class MyClass 
{ 
    private readonly ICalculator _calculator; 

    public MyClass(ICalculator _calculator) 
    { 
     this._calculator = _calculator; 
    } 

    public decimal CalculateComplicatedValue1(MyClassDataPOCO data) 
    { 

    } 

    public decimal CalculateComplicatedValue2(MyClassDataPOCO data) 
    { 

    } 

мне не понравилось это по разным причинам

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

Третье направление (возможно только ты класс должен быть создан через статический фабричный метод):

public class MyClass 
{ 
    private readonly ICalculator _calculator; 
    private MyClassDataPOCO _data; 

    private MyClass(ICalculator _calculator) 
    { 
     this._calculator = _calculator; 
    } 

    public static MyClass Create(MyClassDataPOCO data) 
    { 
     return Create(_container.GetInstance<ICalculator>(), data); 
    } 


    public static MyClass Create(ICalculator calculator, MyClassDataPOCO data) 
    { 
     //do some input validation here 

     var myReturn = new MyClass(calculator); 
     myReturn._data = data; 
     return myReturn; 
    } 

Я думаю, из всех вариантов я люблю это одно лучшее. Единственное, что мне не нравится, - это иметь две функции создания, чтобы их можно было тестировать на единицу (так что я могу добавить ICalculator).

Единственный вариант, который я не пробовал, - это инъекция свойств, потому что id не думал, что было бы неплохо вводить ваши данные через свойства.

+0

Автомобиль подходит для вашего случая? Так что вы можете инкапсулировать логику популяции данных внутри профилировщика картографа или вводить через ioc в качестве зависимости. Если не подходит, я бы хотел знать, почему именно – Ming

+0

@ming. Я не понимаю, что вы получаете здесь на 100%. Я никогда не использовал automapper, но я думаю, что понимаю основные понятия (конвертировать из одного типа данных в другой). Как это мне помогает? – coding4fun

ответ

2

Вы разрабатываете объект домена (DO) на основе бизнес-концепции и прецедентов. По моему опыту, это означает, что ваши объекты должны быть довольно тонкими. DO реализуется на основе определения концепции. Бизнес-прецедент реализуется в сервисе (может быть сервисом приложения, может быть доменным сервисом, зависит от контекста), который будет использовать DO для обновления.

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

О сохранении, так как я использую CQRS, я забочусь только об сохранении/получении объекта. Лично я предпочитаю json-объект (если я не использую источник событий), поэтому save = serialize, get = deserialize. Об инкапсуляции вы можете настроить сериализатор json для работы с частными свойствами и в основном с частными свойствами - это единственный компромисс, который вы делаете.

Как я уже говорил, прецедент реализован как услуга, поэтому в вашем сценарии MyClass на самом деле является сервисом, а не DO. В качестве правила большого пальца DO содержит только данные и поведение, которые помогают определить объект. CalculateComplicatedValue не похож на часть концепции, но это выглядит как прецедент, поэтому сервис.

Здесь нет необходимости в создании фабрики, создание экземпляра DO обычно является простым, однако сервис обычно создается экземпляром DI Container, поскольку в большинстве случаев служба использует другие службы (например, репозиторий или валидатор).

+0

ничего себе, что отличная статья на мой вопрос. Это определенно заставило меня задуматься. Хотелось бы, чтобы мы продолжили этот разговор, к сожалению, SO не настроен для этого. Поэтому я выгляжу так, как будто я шел по пути создания объектов GOD. Я хочу узнать CQRS в какой-то момент, но мне нужно хорошо понять DDD, прежде чем я даже подумаю о том, чтобы спуститься по этому пути. – coding4fun

+1

@ coding4fun Не стесняйтесь читать [мои статьи] (http://blog.sapiensworks.com/topics/#domain-driven-design) о DDD и CQRS – MikeSW

Смежные вопросы