如何设计可通过参数选择实现类的IIdentifierManager通用方案?
优化IIdentifierManager的调用设计方案
问题背景
我定义了如下接口:
public interface IIdentifierManager { Task<bool> Method1(string identifierName, string identifier); Task<bool> Method2(IEnumerable<string> ids); }
已有五个类实现该接口(如CatIdentifierManager),当前持有接口集合IEnumerable<IIdentifierManager> idManagers,并通过多次OfType调用获取不同实现:
var myVar1 = idManagers.OfType<JoeIdentifierManager>()?.FirstOrDefault(); var myVar2 = idManagers.OfType<HisIdentifierManager>()?.FirstOrDefault(); // ... 其他三个类型的获取逻辑
希望通过创建主实现类整合这些实现,通过传入参数指定使用哪一个实现,优化现有设计。
解决方案:使用Facade模式创建统一管理类
方案一:枚举标识+字典映射(推荐)
通过枚举明确标识不同管理器类型,内部用字典维护类型与实现的映射,调用时传入枚举值即可指定使用的实现。
- 定义枚举标识管理器类型
public enum IdentifierManagerType { Joe, His, Her, Cat, Dog }
- 创建主管理类
public class MainIdentifierManager { private readonly Dictionary<IdentifierManagerType, IIdentifierManager> _managerMap; // 构造时注入所有实现,初始化映射关系 public MainIdentifierManager(IEnumerable<IIdentifierManager> idManagers) { _managerMap = idManagers.ToDictionary( manager => manager switch { JoeIdentifierManager => IdentifierManagerType.Joe, HisIdentifierManager => IdentifierManagerType.His, HerIdentifierManager => IdentifierManagerType.Her, CatIdentifierManager => IdentifierManagerType.Cat, DogIdentifierManager => IdentifierManagerType.Dog, _ => throw new ArgumentOutOfRangeException(nameof(manager), "未知的管理器类型") }, manager => manager); } // 封装指定类型的Method1调用 public async Task<bool> Method1(IdentifierManagerType type, string identifierName, string identifier) { if (!_managerMap.TryGetValue(type, out var manager)) throw new ArgumentException("无效的管理器类型", nameof(type)); return await manager.Method1(identifierName, identifier); } // 封装指定类型的Method2调用 public async Task<bool> Method2(IdentifierManagerType type, IEnumerable<string> ids) { if (!_managerMap.TryGetValue(type, out var manager)) throw new ArgumentException("无效的管理器类型", nameof(type)); return await manager.Method2(ids); } }
- 调用方式
// 注入MainIdentifierManager(或直接实例化) var mainManager = new MainIdentifierManager(idManagers); // 指定Cat类型调用Method1 var result = await mainManager.Method1(IdentifierManagerType.Cat, "catId", "123");
方案二:泛型类型指定
如果不想定义枚举,也可以通过泛型类型参数指定要使用的实现,适合强类型场景。
public class MainIdentifierManager { private readonly Dictionary<Type, IIdentifierManager> _managerMap; public MainIdentifierManager(IEnumerable<IIdentifierManager> idManagers) { _managerMap = idManagers.ToDictionary(m => m.GetType(), m => m); } public async Task<bool> Method1<T>(string identifierName, string identifier) where T : IIdentifierManager { if (!_managerMap.TryGetValue(typeof(T), out var manager)) throw new ArgumentException($"未找到类型为{typeof(T).Name}的管理器"); return await manager.Method1(identifierName, identifier); } public async Task<bool> Method2<T>(IEnumerable<string> ids) where T : IIdentifierManager { if (!_managerMap.TryGetValue(typeof(T), out var manager)) throw new ArgumentException($"未找到类型为{typeof(T).Name}的管理器"); return await manager.Method2(ids); } }
调用方式:
var result = await mainManager.Method1<CatIdentifierManager>("catId", "123");
优化优势
- 避免重复的
OfType硬编码,统一维护类型映射逻辑 - 集中处理类型查找异常,减少调用端的异常处理代码
- 调用语义更清晰,通过枚举或泛型明确指定要使用的实现
内容的提问来源于stack exchange,提问作者Bohn
相关产品推荐
相关产品推荐

