重构对一堆构造函数的调用,这些构造函数都使用相同的参数

本文关键字:构造函数 参数 调用 重构 一堆 | 更新日期: 2023-09-27 18:26:17

我该如何重构这个:

if (cond1) {
    return new Class1(arg1, arg2, arg3);
}
else if (cond2) {
    return new Class2(arg1, arg2, arg3);
}
else if (cond3) {
    return new Class3(arg1, arg2, arg3);
}
...

我特别感兴趣的是避免重复arg1, arg2, arg3

重构对一堆构造函数的调用,这些构造函数都使用相同的参数

制作一个工厂函数:

template<class Derived>
Base* instantiate(A arg1, B arg2, C arg3) {
    return new Derived(arg1, arg2, arg3);
}

使用有意义的密钥类型构建地图:

std::map<int, Base(*)(A, B, C)> factory;
factory[0] = instantiate<Class1>;
factory[1] = instantiate<Class2>;
factory[2] = instantiate<Class3>;

是的,对于int,它可能只是一个数组或std::vector,但我使用上面的std::map是为了提供一个通用的解决方案。然后,您可以以显而易见的方式从工厂获取实例。对于任意条件,它必须是这样的:

int index = cond1 ? 0
    : cond2 ? 1
    : cond3 ? 2
    : throw std::runtime_error("Invalid index.");
return factory[index](arg1, arg2, arg3);

但根据问题的具体情况,可能有一种更明智的方法可以做到这一点。

使用激活器

Type t = cond1 ? typeof(Class1) : cond2 ? typeof(Class2) : cond3 ? typeof(Class3) : null;
Activator.CreateInstance(t, new object[] {arg1, arg2, arg3});