2009-11-19 42 views
0

我们有一个类的事件(它不同的名字,但我只是做抽象):可以/应该域对象负责将自己转换为另一种类型?

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

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

真正的问题是:域对象是否可以为这样的转换负责,或者你会不会推荐它?我会避免丑陋的switch语句,但在其他地方增加复杂性。

回答

1

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

2

虽然我同意托马斯的观点,但您可能需要查看以下设计模式看他们是否帮助你:

  • 位访客模式
  • 双重分发模式
  • Builder模式
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); 
} 

这是相当类似工厂模式,但如果你是依赖于事件类型,它可以做到这一点,如:

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

在为了获得可读性

var message = eventInstance.AsMessage(); 

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

0

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

这会给你两全其美。

相关问题