dev*_*969 0 c# design-patterns
嗨想知道是否有更好的方法来删除其他if语句并使用策略模式.有任何想法吗?
public async Task<TResponse> HandleResponseAsync<TRequest, TResponse>(TRequest item)
where TResponse : class, new()
{
TResponse result = default(TResponse);
Type currentResponseType = typeof(TResponse);
if (currentResponseType == typeof(MyResponseA))
{
result = //dosomething
}
else if (currentResponseType == typeof(MyResponseB))
{
result = //dosomething
}
else if (currentResponseType == typeof(MyResponseC))
{
result = //dosomething
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
在泛型方法中使用特定的子类是一种非常危险的方法,因为它通过将您锁定到泛型方法内的类列表来限制未来的灵活性.它还抛弃了使其成为通用方法所能获得的大部分优势.
由于您已经需要无参数构造函数,因此一种方法是为您TResponse的接口提供一个接口,并使用该接口回调实例以获得正确的结果:
interface IResponse {
void Configure(); // Use custom parameters if necessary
}
public async Task<TResponse> HandleResponseAsync<TRequest, TResponse>(TRequest item) where TResponse : class, new(), IResponse {
TResponse result = new TResponse();
result.Configure(...);
}
Run Code Online (Sandbox Code Playgroud)
现在来自if-then-else块的代码将进入Configure相应IResponse实现的方法:
class MyResponseA : IResponse {
public MyResponseA() {}
public void Configure() {
// dosomething from the first IF
}
}
class MyResponseB : IResponse {
public MyResponseB() {}
public void Configure() {
// dosomething from the second IF
}
}
Run Code Online (Sandbox Code Playgroud)
注意:如果不同的实例需要HandleResponseAsync传递给他们的不同信息,事情可能会变得棘手.在这种情况下,您还应该创建一个对象,该对象包含任何实现可能需要的所有信息,以便完成其Configure方法.
如果你打开泛型的类型,你可能做错了.泛型应该是通用的.你编写的代码不是通用的,它非常脆弱,而且泛型使它更多,而不是更简单.
在这里,让我为你重写一下:
if (currentResponseType == typeof(MyResponseA))
return (TResponse) HandleResponseA(item);
else if (currentResponseType == typeof(MyResponseB))
return (TResponse) HandleResponseB(item);
else if (currentResponseType == typeof(MyResponseC))
return (TResponse) HandleResponseC(item);
Run Code Online (Sandbox Code Playgroud)
如果有通过该方法三种可能的代码路径,没有更多的,毫不逊色,然后简单地写三种方法HandleResponseA,HandleResponseB,HandleResponseC.这就是你已经做过的事情,你只需将每个方法的主体作为一个体的主体if.这里没有任何节省的方法; 你刚刚做了一个脆弱的,过于复杂的方法.现在我们已经重构了你的方法,我们发现我们可以完全删除该方法并直接调用适当的处理程序.
另外,考虑一下你的穷人!在通话现场,没有令人信服的理由更喜欢HandleResponseAsync<Giraffe, MyResponseB>(giraffe)更好HandleResponseB(giraffe); 如果有三种方法而不是一种方法,呼叫站点更短,更清晰,更安全.
此外,如果此处提供的服务100%依赖于响应对象的类型,那么为什么这不是响应对象的关注点?为什么呼叫站点实际上不是MyResponseB.Handle(giraffe)?方法可以是响应类型的静态方法.如果您要编写三个方法体,每种类型一个,则将它们放在该类型上.