可以/应该由域对象负责将自身转换为其他类型吗?

时间:2009-11-19 12:17:05

标签: domain-driven-design

我们有一个类事件(它的实际命名不同,但我只是在进行抽象):

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 FirstMessageclass SecondMessage,并使域对象负责构建消息。

我希望它不是太抽象。底线是我们需要将一个类转换为另一个类。一个简单的映射器不会这样做,因为存在具有XML内容的属性等(由于遗留应用程序生成事件)。接受我们在这里尝试做的事情。

真正的问题是:域对象可以对此类转换负责,还是不推荐它?我会避免使用丑陋的switch语句,但会在其他地方增加复杂性。

5 个答案:

答案 0 :(得分:2)

虽然我同意Thomas的观点,但您可能需要查看以下设计模式,看看它们是否对您有所帮助:

  • Vistor Pattern
  • Double-Dispatch Pattern
  • 构建器模式

答案 1 :(得分:1)

严格地说,域对象不应该对表示域之外的任何事情负责。 “改变类型”显然是一个技术问题,应该通过某种服务类来完成,以保持明确的关注点分离......

答案 2 :(得分:1)

为了获得

的可读性
var message = eventInstance.AsMessage();

遵循单一责任原则,您可以将“Message()定义为事件类型的扩展方法。”

答案 3 :(得分:0)

几乎没有可能的解决方案。要使用抽象工厂:

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);
}

答案 4 :(得分:0)

我会将逻辑封装到单独的Factory / Builder类中,使用Event上的扩展方法来调用构建器。

这会给你两全其美。