Domain driven design 域对象是否可以/应该负责将自身转换为其他类型?

Domain driven design 域对象是否可以/应该负责将自身转换为其他类型?,domain-driven-design,Domain Driven Design,我们有一个类事件(它的名称实际上有所不同,但我只是进行抽象): 我们需要使用此对象构建消息类的实例,但根据EventType,我们使用不同的生成器: switch (event.EventType) { case EventType.First: message = FirstMessageBuilder.Build(event); break; case EventType.Second: message = SecondMess

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

我们需要使用此对象构建消息类的实例,但根据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();
}
然后派生两个类:
classfirstmessage
classsecondmessage
,并使域对象负责构建消息

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


真正的问题是:域对象可以负责这样的转换吗,或者您不建议这样做?我会避免使用丑陋的switch语句,但会在其他地方增加复杂性。

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

严格来说,域对象不应负责表示域以外的任何事情。“更改类型”显然是一个技术问题,应该由某种服务级别来完成,以保持问题的清晰分离…

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

  • Vistor模式
  • 双重调度模式
  • 构建器模式

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

  • Vistor模式
  • 双重调度模式
  • 构建器模式

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

      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);
      }
      
      公共接口IAssembler
      {
      t估计变换(t源);
      }
      
      这与factory模式非常相似,但如果您依赖于EventType,则可以按如下方式执行:

      public interface IAssembler<TEventType> 
      {
          object Transform(object source);
      }
      
      公共接口IAssembler
      {
      对象变换(对象源);
      }
      
      几乎没有可能的解决方案。要使用抽象工厂:

      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);
      }
      
      公共接口IAssembler
      {
      t估计变换(t源);
      }
      
      这与factory模式非常相似,但如果您依赖于EventType,则可以按如下方式执行:

      public interface IAssembler<TEventType> 
      {
          object Transform(object source);
      }
      
      公共接口IAssembler
      {
      对象变换(对象源);
      }
      
      以获得

      var message = eventInstance.AsMessage();
      

      除了遵循单一责任原则外,还可以将as
      Message()
      定义为事件类型的扩展方法。

      以获得

      var message = eventInstance.AsMessage();
      

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

      我将把逻辑封装到一个单独的Factory/Builder类中,并在
      事件上使用扩展方法来调用生成器


      这将使您两全其美。

      我将把逻辑封装到一个单独的Factory/Builder类中,并在
      事件上使用扩展方法调用生成器

      这会让你两全其美