public interface IPay {
void DoAction(Employee employee);
}
public class A : IPay {
public void DoAction(Employee employee) {
Console.WriteLine("{0} level up", employee.Name);
}
}
public class B : IPay {
public void DoAction(Employee employee) {
Console.WriteLine("{0} got a raise", employee.Name);
}
}
public class C : IPay {
public void DoAction(Employee employee) {
Console.WriteLine("{0} nothing happened", employee.Name);
}
}
public class D : IPay {
public void DoAction(Employee employee) {
Console.WriteLine("{0} got a pay cut", employee.Name);
}
}
public class E : IPay {
public void DoAction(Employee employee) {
Console.WriteLine("{0} is fired", employee.Name);
}
}
public abstract class Evaluation { }
public class Employee2 {
public string Name;
public Evaluation Evaluation;
}
public class LevelA : Evaluation { }
public class LevelB : Evaluation { }
public class LevelC : Evaluation { }
public class LevelD : Evaluation { }
public class LevelE : Evaluation { }
switch/case
和if/else
一样,是常用的条件判断/流程控制方法。 想象一个场景:公司给员工考评有A/B/C/D/E这5个评级,A级能得到升职、B级可以加薪、C级合格也就没什么变化、D级不太合格需要降薪、E级很不合格基本等着被解雇。写程序进行处理时,通常的switch/case
写法:可以看到,随着判断条件的增多,
switch/case
和if/else if/else
一样,代码的可读性、可维护性严重下降。那么有什么办法可以替代?今天我们就简单来聊聊3种常用的。字典+代理是比较简单的一种实现:
根据字典的key来进行查找,当需要增加新的
case
分支的时候,只需要编写新的处理方法,并且在字典中增加一对key/value就可以了。代码简洁美观,没有一长串令人厌烦的case
了。这个只是稍微复杂一点点。 先建个接口/基类,然后建些类实现这个接口/基类:
然后就是调用:
构建稍微复杂的结果,就是在需要新增
case
分支时,只用新增一个继承了接口/基类的子类,实现内部的处理方法,就完成了。这个其实不太适合当前场景,更适合可以抽象出接口/基类的对象作为
switch
的判断条件时。这里我们权当评级是这样的一个对象。 改造Employee
类及相关Evaluation
类:调用及实现:
这里必须要一个
DoAction(dynamic evaluation, string name)
的动态方法进行中转。如果没有该中转,由于调用方法的参数类型是基类,下面没有匹配的方法可直接进入,编译无法通过;如果是以基类类型作为中转方法的参数,编译倒是能通过,但你将因无限套娃调用,而见到著名的StackOverFlow
异常。 这里,我们也可以看到,增加case
时的工作量,也仅仅是实现一个Evaluation
的子类,以及相应处理方法的事。下一篇将是 替代switch/case之Android篇