Может / должен ли объект домена отвечать за преобразование себя в другой тип? - PullRequest
0 голосов
/ 19 ноября 2009

У нас есть класс Event (на самом деле он называется по-разному, но я просто делаю абстракцию):

public class Event
{
    public string Name { get; set; }
    public string Description { get; set; }
    public EventType EventType { get; set; }
}

Нам нужно создать экземпляр класса Message с этим объектом, но в зависимости от EventType мы используем другой компоновщик:

switch (event.EventType)
{
    case EventType.First:
        message = FirstMessageBuilder.Build(event);
        break;
    case EventType.Second:
        message = SecondMessageBuilder.Build(event);
        break;
}

Считаете ли вы это приемлемым, или мы должны использовать следующий подход:

Сделать абстрактный класс:

public class Event
{
    public string Name { get; set; }
    public string Description { get; set; }
    public abstract Message BuildMessage();
}

Затем выведите два класса: class FirstMessage и class SecondMessage и возложите ответственность за создание сообщения на доменные объекты.

Надеюсь, это не слишком абстрактно. Суть в том, что нам нужно преобразовать один класс в другой. Простой маппер не подойдет, потому что есть свойства с содержимым XML и тому подобное (из-за того, что приложение создает события). Просто прими то, что мы пытаемся сделать здесь.

Реальный вопрос: может ли доменный объект отвечать за такое преобразование или вы не порекомендовали бы его? Я бы избегал уродливого оператора switch, но добавил бы сложность где-нибудь еще.

Ответы [ 5 ]

2 голосов
/ 19 ноября 2009

Хотя я согласен с Томасом, возможно, вы захотите взглянуть на следующие шаблоны проектирования, чтобы узнать, помогают ли они вам:

  • Vistor Pattern
  • Шаблон двойной отправки
  • Образец строителя
1 голос
/ 19 ноября 2009

Чтобы получить читабельность

var message = eventInstance.AsMessage();

также, следуя принципу единой ответственности, вы можете определить As Message() как метод расширения типа события.

1 голос
/ 19 ноября 2009

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

0 голосов
/ 20 ноября 2009

Я бы инкапсулировал логику в отдельный класс Factory / Builder, и использовали бы метод расширения в Event для вызова построителя.

Это даст вам лучшее из обоих миров.

0 голосов
/ 19 ноября 2009

Есть несколько возможных решений. Чтобы использовать абстрактную фабрику:

public interface IMessageFactory 
{
    Message Create();
}

public class FirstMessageFactory : IMessageFactory
{
    public Message Create()
    {
        //...
    }
}

public class SomeService
{
     private readonly IMessageFactory _factory;

     public SomeService(IMessageFactory factory)
     {
          _factory = factory;
     }

     public void DoSomething() 
     {
         var message = _factory.Create();
         //...
     }
}

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

Чтобы использовать Ассемблер, который выполняет преобразование:

public interface IAssembler<TSource, TDestination> 
{
    TDestination Transform(TSource source);
}

Это очень похоже на фабричный шаблон, но если вы зависите от EventType, это можно сделать так:

public interface IAssembler<TEventType> 
{
    object Transform(object source);
}
...