You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何设计可通过参数选择实现类的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模式创建统一管理类

方案一:枚举标识+字典映射(推荐)

通过枚举明确标识不同管理器类型,内部用字典维护类型与实现的映射,调用时传入枚举值即可指定使用的实现。

  1. 定义枚举标识管理器类型
public enum IdentifierManagerType
{
    Joe,
    His,
    Her,
    Cat,
    Dog
}
  1. 创建主管理类
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);
    }
}
  1. 调用方式
// 注入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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 04:01:00