代码之家  ›  专栏  ›  技术社区  ›  Peter Alexandr Nikitin

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

  •  0
  • Peter Alexandr Nikitin  · 技术社区  · 15 年前

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

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

    我们需要用这个对象构建一个消息类的实例,但是根据事件类型,我们使用不同的生成器:

    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 回复  |  直到 15 年前
        1
  •  1
  •   Thomas Weller    15 年前

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

        2
  •  2
  •   Codebrain    15 年前

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

    • 访问者模式
    • 双调度模式
    • 生成器模式
        3
  •  1
  •   Martin R-L    15 年前

    为了获得

    var message = eventInstance.AsMessage();
    

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

        4
  •  0
  •   Marek Tihkan    15 年前

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

    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);
    }
    
        5
  •  0
  •   Vijay Patel    15 年前

    我将把逻辑封装到一个单独的工厂/构建器类中, 在上使用扩展方法 Event 打电话给建筑商。

    这会让你两全其美。