用表驱动法和Reflection实现代码重构

posted at 2021.9.5 17:20 by 风信子

表驱动法是一种设计思路,可以称为模式,也可以简单理解为查字典,例如有一个枚举类型Week

        enum Week

        {

            Monday,

            Tuesday,

            Wednesday,

            Thursday,

            Fridey,

            Saturday,

            Sunday

        }

如果要把Week的元素值用中文输出,简单而丑陋的方法也许是封装一个GetChineseWeek方法。

static string GetChineseWeek(Week week)

        {

            switch (week)

            {

                case Week.Monday:

                    return "星期一";

                case Week.Tuesday:

                    return "星期二";

                case Week.Wednesday:

                    return "星期三";

                case Week.Thursday:

                    return "星期四";

                case Week.Fridey:

                    return "星期五";

                case Week.Saturday:

                    return "星期六";

                case Week.Sunday:

                    return "星期日";

                default:

                   throw new ArgumentOutOfRangeException("week", "星期值超出范围");

            }

        }

之所以说这种方法是丑陋的,原因在于两点:

1)分支太长了,而且出现了重复代码。

2)不利于扩展。如果出现星期八、星期九怎么办?

当然,星期制已经是固定的了,应该不会出现扩展的情况。但是,换种情景来考虑,假设我们正在渲染动画怎么办?谁知道下一秒美工会提交我多少个动画呢?

一种解决方案是使用多态,它很好地符合了“开闭”原则。如果增加条件分支,不必修改原有代码,直接增加子类就可以了。利用多态来避免多分支,这里暂且不表,采用“表驱动法”的代码如下所示:

Static void Mainstring[] args

{

    Console.WriteLineGetChineseweekInTableweek.Friday))

}

        static string GetChineseInTable(Week week)

        {

            string[] ChineseTable = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };

            return ChineseTable[(int)week];

        }

这是一种按照索引值驱动的表驱动法。枚举元素所代表的整型值,很容易和字符申数组索引组合起来了,用两行语句就可以完美地替代原先的GetChineseWeek方法。

但是,这种方法有局限性,完成的功能也很有效,如果将需求换成:星期一Mike打扫卫生、星期二Rose清理衣柜、星期三MikeRose没事可以吵吵架、星期四Rose要去Shopping......也就是说需求由静态属性变成了动态行为,那么事情就变得复杂了。

遇上这种情况,我们可能会想到使用多态,在这里仍然使用表驱动法+反射reflection来实现这类动态的行为,代码如下所示:

       static void Main(string[] args)

        {

            //Console.WriteLine(GetChineseWeek(Week.Monday));

            //Console.WriteLine(GetChineseInTable(Week.Thursday));

            SampleClass sample = new SampleClass();

            Var addMethod = typeof(SampleClass).GetMethod(ActionInTable(Week. Tuesday));

             addMethod.Invoke(sample, null);

        }

        static string ActionInTable(Week week)

        {

            string[] methods = { "Cleaning", "CleanCloset", "Quarrel", "Shopping", "Temp", "Temp", "Temp" };

            return methods[(int)week];

        }

        class SampleClass

        {

            public void Cleaning()

            {

                Console.WriteLine("打扫");

            }

            public void CleanCloset()

            {

                Console.WriteLine("清理衣柜");

            }

            public void Quarrel()

            {

                Console.WriteLine("吵架");

            }

            public void Shopping()

            {

                Console.WriteLine("购物");

            } 

        }

     控制台实际效果如下图所示:

Tags: , , ,

IT技术 | 防控BUG

Add comment

  Country flag

biuquote
微笑得意调皮害羞酷大笑惊讶发呆喜欢可怜尴尬闭嘴噘嘴皱眉伤心抓狂呕吐坏笑漫骂发怒
Loading