重构一则

有时我们会遇到某个方法其实是一个配置接口,需传入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);
    //其他代码
}

我们可以看到,这个重构对方法实现并没有好处而言,但却增加了方法签名的清晰,使调用者更方便的使用,同时增强了代码可读性

posted @ 2010-10-28 10:09  他山之石_  阅读(1720)  评论(4编辑  收藏  举报