重构一则
有时我们会遇到某个方法其实是一个配置接口,需传入N个bool值,表示某些选项是否有效,很有可能签名是这样的:
public void SomeMeth(bool IsCfg1, bool IsCfg2, bool IsCfg3, bool IsCfg4, bool IsCfg5)
这样在调用时可得小心翼翼的按位置相关,传入每一个参数
cls.SomeMeth(true,false,true,false,false); cls.SomeMeth(false,false,true,false,true);
有一种重构手法是将这些配置项统一成一个字典,将字典做为参数传给方法,但今天我们将使用另一种方法进行重构
首先,将所有参数声明成一个Flag类型的枚举的成员
[Flags] public enum CfgTyp { None = 0, Cfg1 = 1, Cfg2 = 1 << 1, Cfg3 = 1 << 2, Cfg4 = 1 << 3, Cfg5 = 1 << 4 }
再将方法重新定义为
public void SomeMeth(CfgTyp cfg)
这样我们在调用时可以很自由的组合各个参数,一位置不相关,二数量不相关,并且增加了可读性,比如
cls.SomeMeth(CfgTyp.Cfg1 | CfgTyp.Cfg2); cls.SomeMeth(CfgTyp.Cfg3 | CfgTyp.Cfg4 | CfgTyp.Cfg5); cls.SomeMeth(CfgTyp.None);
在方法体内部其实还需要将枚举转换成bool
public void SomeMeth(CfgTyp cfg) { bool IsCfg1 = ((cfg & CfgTyp.Cfg1) == CfgTyp.Cfg1); bool IsCfg2 = ((cfg & CfgTyp.Cfg2) == CfgTyp.Cfg2); bool IsCfg3 = ((cfg & CfgTyp.Cfg3) == CfgTyp.Cfg3); bool IsCfg4 = ((cfg & CfgTyp.Cfg4) == CfgTyp.Cfg4); bool IsCfg5 = ((cfg & CfgTyp.Cfg5) == CfgTyp.Cfg5); //其他代码 }
我们可以看到,这个重构对方法实现并没有好处而言,但却增加了方法签名的清晰,使调用者更方便的使用,同时增强了代码可读性