以前在 csdn上看到一篇 “你还在使用if/else吗?”文章,提到如果你还在使用if语句,那么你就需要对你的代码重构。那篇文章许多人的评论上褒贬不一,但我现在想举的一个例子是对if/else的重构。(当然,是从别人那偷学来的,^_^)。
enum employeetype
{
salers;
engineer;
manager;
}
if(employee==emloyeetype.salers)
{
//做什么
}
else if(employee==employeetype.manager)
{
//做什么
}
//................
这样写未尝不可,但是如果要是新加入一个角色,那么会如何处理呢?你就需要修改哪个枚举,并且后贴上个if/else,那么我按照面向对象的想法来实现重构呢?
abstract class employee
{
//.....写一个抽象类,包括一个抽象方法
}
class manager:employee
{
//..... 子类继承并重新抽象方法
}
//......other roles classes
class Salary
{
static void Main()
{
employee em = new Manager();
em.Getsalary();
}
}
例子二
重构之前的代码
private static void OldMethod(BusinessObjectInfo parentBOInfo)
{
IList<BusinessObjectsPropertyInfo> bosPropertyInfo = parentBOInfo.BOsPropertyInfos;
if ((bosPropertyInfo.Count == 1) && (null != parentBOInfo.TreeChildPropertyInfo))
{
//action one
}
else if (((bosPropertyInfo.Count > 1) && (null != parentBOInfo.TreeChildPropertyInfo))
|| ((bosPropertyInfo.Count > 0) && (null == parentBOInfo.TreeChildPropertyInfo)))
{
//action two
}
}
初步重构
private static void NewMethod(BusinessObjectInfo parentBOInfo)
{
IList<BusinessObjectsPropertyInfo> childrenProperties = parentBOInfo.BOsPropertyInfos;
var childrenPropertiesCount = childrenProperties.Count;
if (childrenPropertiesCount <= 0)
{
return;
}
var hasTreeChild = null != parentBOInfo.TreeChildPropertyInfo;
if (hasTreeChild)
{
if (childrenPropertiesCount == 1)
{
//action one
}
}
else
{
//action two
}
}
以上两种写法并不完全等价(你能找出来吗?),不过就当时的业务逻辑来说,这样写是没错的。
最终版本 if判断时简洁处理只使用必要的参数 合并if到同一级别
上面的写法,还是错了,应该是这样:
private static void NewMethod2(BusinessObjectInfo parentBOInfo)
{
IList<BusinessObjectsPropertyInfo> childrenProperties = parentBOInfo.BOsPropertyInfos;
var childrenPropertiesCount = childrenProperties.Count;
if (childrenPropertiesCount <= 0)
{
return;
}
var hasTreeChild = null != parentBOInfo.TreeChildPropertyInfo;
if (hasTreeChild && childrenPropertiesCount == 1)
{
//action one
}
else
{
//action two
}
}
例子三
if(protocolName.contains("a")){
dosomething
}else if(protocolName.contains("b")){
dosomething
}else if(protocolName.contains("c")){
dosomething
}else if(protocolName.contains("d")){
dosomething
}
对于这些重构可以使用反射或者注解,但是现实开发中不建议使用
public interface Logic {
void doLogic();
}
Map<String, Logic> determine = new HashMap<String, Logic>();
determine.put("a", new Logic() {
public void doLogic() {
//...字符串为"a"时真正要做的逻辑
}
}
);
determine.put("b", new Logic(){...});
...
String string = "a";
// 这一段就代替了switch的判断功能
Logic logic = determine.get(string);
// 执行逻辑
if (logic != null) {
logic.doLogic();
}
这个例子是用多态来解决if/else结构中的多重选择问题,使得但变化来临时,只需要对系统进行扩展,而不是修改,开闭原则(ocp)即是此意。