分享

降低代码复杂度的一种方法

 东北十三少 2021-10-18

代码之所以复杂,有以下两种原因:

一是耦合度高。如果一个代码单元是由多个小的代码单元耦合而成,那么它的复杂度就是其中各个小代码单元的复杂度的总和;二是使用了非常长的链式(连续的)if-then-elase语句或者switch语句,代码单元包含很多个分支。

降低代码的复杂度,要根据代码复杂的原因采取相应的方法。对于第一种情况,由于代码单元中含有了许多几乎互不相关的代码块,这时候就适合采用“提取方法”的技巧来进行重构,以降低复杂度。

对于第二种情况,代码单元有太多的分支,而一般能够接受的分支数量是不多于4个。下面以一个会返回正确的国旗颜色的GetFlagColors方法重构为例来演示下降低其复杂度的方法。

public IList<Color> GetFlagColors(Nationality nationality)
{
List<Color> result;
switch (nationality)
{
case Nationality,DUTCH:
result = new List<Color> { Color.Red, Color.White, Color.Blue}; break;
case Nationality.GERMAN:
result = new List<Color> { Color.Black, Color.Red, Color.Yellow};
break;
case Nationality.BELGIAN:
result = new List<Color> {Color.Black, Color.Yellow, Color.Red };
break;
case Nationality.FRENCH:
result = new List<Color> {Color. Blue, Color.White, Color.Red};
break;
case Nationality.ITALIAN:
result = new List<Color> { Color.Green, Color.White, Color.Red };
break;
case Nationality,UNCLASSIFIED:
default:
result = new List<Color> { Color,Gray };
break;
}
return result;
}

方法体中的switch语句需要处理所有的国家枚举类型,并返回每个国家对应的正确国旗颜色。这个方法中需要测试的分支为6。

要减少这个方法的分支数量,可以使用“使用多态来代替条件判断”的重构技巧,让每个国旗都拥有一个自己的类型,并实现同一个接口。

为此,我们首先定义一个公用的Flag接口:

public interface IFlag
{
IList<Color> Colors
{
get;
}
}

然后再为不同的国家定义不同的国旗类型,例如荷兰:

public class DutchFlag: IFlag
{
public IList<Color> Colors
{
get
{
return new List<Color { Color.Red, Color.White, Color.Blue };
}
}
}

最终重构后代码如下:

private static readonly Dictionary<Nationality, IFlag>FLAGS = new Dictionary<Nationality, IFlag>();

static FlagFactory()
{
FLAGS[Nationality.DUTCH]= new DutchFlag();
FLAGS[Nationality.GERMAN] = new GermanFlag();
FLAGS[Nationality.BELGIAN] = new BelgianFlag();
FLAGS [Nationality.FRENCH]= new FrenchFlag();
FLAGS[Nationality.ITALIAN] = new ItalianFlag();
}

public IList<Color> GetFlagColors(Nationality nationality)
{
IFlag flag = FLAGS[nationality];
flag = flag ?? new DefaultFlag();
return flag.Colors;
}

这种重构技巧去掉了switch语句,极大地降低了代码的复杂度,而且可以根据需要不断增加所支持的国旗种类。不过,这种方式的不好之处是引入了更多的类和代码。

这正是:

若要降低复杂度,复杂原因搞清楚

提取方法去耦合,减少分支用类库

参考书目:代码不朽:编写可维护软件的十大要则,作者:(荷兰)约斯特·维瑟,译者:张若飞,出版社:电子工业出版社

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多