如何优雅调用签名近乎一致的Handler处理器?
优雅解决方案推荐
针对你遇到的「部分处理器需要额外参数,类型判断调用繁琐」的问题,这里提供两种更优雅的实现思路,避免类型判断同时提升扩展性:
方案一:参数封装(最推荐,扩展性强)
把Execute方法的所有参数封装成一个上下文类,后续新增参数只需修改这个类,无需改动接口和调用逻辑,完全符合开闭原则。
实现步骤:
- 定义上下文类,包含所有可能用到的参数:
public class HandlerContext { public SqlConnection SqlConnection { get; set; } public SqlTransaction Transaction { get; set; } public List Data { get; set; } public IConnection ExtraConnection { get; set; } // 新增的可选参数 }
- 修改基础接口和处理器实现:
public interface IHandler { void Execute(HandlerContext context); } public class Handler : IHandler { public void Execute(HandlerContext context) { // 仅使用需要的参数:SqlConnection、Transaction、Data ... } } public class SecondHandler : Handler { public override void Execute(HandlerContext context) { base.Execute(context); // 额外使用ExtraConnection参数 ... } }
- 简化主函数调用:
void Main(IConnect connect) { // 构建上下文对象,按需赋值参数 var handlerContext = new HandlerContext { SqlConnection = connect, Transaction = transaction, Data = data, ExtraConnection = iconnection }; var handler = Config.Get(num); handler.Execute(handlerContext); // 无需任何类型判断 }
方案二:接口重载+默认实现
如果不想改动原有接口的核心逻辑,可以通过接口重载+基础类默认实现的方式,让所有处理器统一支持多参数调用,特殊处理器重写对应方法即可。
实现步骤:
- 扩展基础接口,新增带额外参数的
Execute方法:
public interface IHandler { void Execute(SqlConnection sqlConnection, SqlTransaction transaction, List data); void Execute(SqlConnection sqlConnection, IConnection connection, SqlTransaction transaction, List data); }
- 在基础
Handler类中为新增方法提供默认实现:
public class Handler : IHandler { public void Execute(SqlConnection sqlConnection, SqlTransaction transaction, List data) { ... } // 默认忽略额外参数,调用基础方法 public virtual void Execute(SqlConnection sqlConnection, IConnection connection, SqlTransaction transaction, List data) { Execute(sqlConnection, transaction, data); } }
- 特殊处理器重写新增方法:
public class SecondHandler : Handler { public override void Execute(SqlConnection sqlConnection, IConnection connection, SqlTransaction transaction, List data) { base.Execute(sqlConnection, transaction, data); // 使用额外的connection参数 ... } }
- 主函数统一调用多参数方法:
void Main(IConnect connect) { // Some code var handler = Config.Get(num); // 无需判断类型,直接调用多参数方法 handler.Execute(connect, iconnection, transaction, data); }
原方案的问题
原方案通过类型判断分支调用的方式,违反了开闭原则——每次新增特殊处理器都需要修改主函数的判断逻辑,后续维护成本会越来越高,且代码可读性差。
内容的提问来源于stack exchange,提问作者MaybeRainQ
相关产品推荐
相关产品推荐

