我们有一个类事件(它的实际命名不同,但我只是在进行抽象):
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语句,但会在其他地方增加复杂性。
答案 0 :(得分:2)
虽然我同意Thomas的观点,但您可能需要查看以下设计模式,看看它们是否对您有所帮助:
答案 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
上的扩展方法来调用构建器。
这会给你两全其美。