【发布时间】:2020-04-30 14:13:53
【问题描述】:
我有一个返回基类响应的服务。它肯定有派生响应。
public class ResponseBase
{
public string Response { get; set; }
}
public class DerivedResponse : ResponseBase
{
public string AdditionalResponse { get; set; }
}
这里是服务代码:
public class SomeService
{
public ResponseBase GetResponse() => new DerivedResponse();
}
然后我需要以不同的方式处理不同的响应。显然尝试通过 100500 if\elses 获得适当的行为不是一个好的解决方案。我决定为每个具体的响应设置一个特殊的响应处理程序。
public interface IHandlerBase<T>
where T : ResponseBase
{
void Handle(T response);
}
public class DerivedResponseHandler : IHandlerBase<DerivedResponse>
{
public void Handle(DerivedResponse response)
{
}
}
此外,我们需要封装行为,这些行为将决定获取什么处理程序以处理具体响应,我认为工厂是一个不错的解决方案。我遇到了一个问题,因为我不知道要返回什么,因为我不知道编译时派生类型:
public class HandlerFactory {
public IHandlerBase<> /*WHAT RETURN HERE*/ CreateHandler(ResponseBase response)
{
//decide the derived type of the 'response' and return appropriate handler
}
}
当然,我们可以删除泛型参数,在所有处理程序中接受基类,然后在具体处理程序中转换为特殊的,但我认为这不是一个好的解决方案。那么您能否建议如何以一种干净的方式做到这一点,也许是一些模式或解决方案?
【问题讨论】:
-
我看到两个选项,你可以给
GetResponse一个通用参数,比如T GetResponse<T>() where T : ResponseBase,或者你可以给CreateHandler一个通用参数,比如IHandlerBase<T> CreateHandler<T>(T response) -
@Ackdari,我不能 1)GetResponse 不能返回泛型
,因为它也是由内部方法确定的,而不是由调用方确定 2)CreateHandler 也不能是泛型的,因为我我打电话给工厂时不知道实际的派生类型。所以工厂应该也可以在内部确定它
标签: c# design-patterns architecture factory-pattern