基本结构:
OO视角的重构技巧-if\switch 的消除private void Invoke(Class obj)
}

凡是符合这种结构的,都可以将dosomething移到obj中作为obj的一个成员,然后实现xClass,yClass,再采用如下方式调用
OO视角的重构技巧-if\switch 的消除private void Invoke(Class obj)
}

扩展结构:
OO视角的重构技巧-if\switch 的消除private void Invoke(Class obj)
}

这种结构的特点就是不再依赖于具体的类型来决定调用何种函数,而是依赖的该类的某个属性。
通常这样的处理,可以采用“化属性为分类”来处理,即重新设计xClass,yClass继承Class,再在xClass,yClass中分别实现dosomething,结果仍成为
   
OO视角的重构技巧-if\switch 的消除private void Invoke(Class obj)
}

扩展结构与基本结构极其类似,实际上,基本结构是对隐含的typename的属性采用了简单的分类处理,而扩展结构是针对objname进行了分类处理。

再次扩展:
OO视角的重构技巧-if\switch 的消除private void Invoke(Class obj)
}

前面的都是针对有统一属性的情况时的处理,大体上上面两种情况,可以解决所有的switch问题,那么,对于非统一属性的处理如何办理?这种仍然大量的if,写起来不但郁闷,维护也很麻烦,如果采用继承细化分类,则会造成更大的困扰。从继承的角度来说,实际上它的原理也就是在内部有一张表进行维护,根据不同的类型调用,会调用该表中指定的函数。

所以对于这样的情况,只要实现一张表,就可以更精细化地控制。

首先要结构一个类似的结构:

OO视角的重构技巧-if\switch 的消除public class obj_method
}

于是,我们就可以创建任意的条件来控制对象调用哪一种方法,在dotnet中,使用delegate直接解决MethodHandle问题,C++中亦有函数指针,所以这也不是问题,那么如果是java一类的语言,应该如何办?答案是实现一个接口IMethod,即:
OO视角的重构技巧-if\switch 的消除public interface IMethod
}

众所周所接口可以粘合类,所以,这里也是一样,Class本身要实现IMethod接口,obj_Method也要实用这样一个接口,然后在Class的dosomething调用obj_method的dosomething就行了。最后,仍然可以采用如下调用:
OO视角的重构技巧-if\switch 的消除private void Invoke(Class obj)
}


更加复杂的扩展:

这种情况下,一般需要考虑状态机来实现一个逻辑管理了,并不是简单的继承或多态能轻易解决的。

总结
由此可以看出,真正避免if的方法是不存在的,但我们可以针对各种不同类型的情况,把需要自己写if的工作转移给框架或系统内部提供的机制来进行处理,这样,可以大大减少调用端代码的逻辑复杂度,从而显得代码更加清楚,实际上这是一种把细颗粒的逻辑放大成了类或对象之间的逻辑。通常情况下,调用端是实现逻辑表现最复杂的部分,所以为了平衡化,大多数时候是把调用端的逻辑复杂度往服务提供端转移,从而使项目中的代码达到更高的一致性,并整体上降低耦合性。
   直观地说,if/switch集中存在的地方往往就是一团疙瘩的地方,必要的逻辑疙瘩是不可解的,但是我们可以把它弄分散,弄平整,从而最大化保证整洁度。 
  

相关文章:

  • 2021-10-25
  • 2022-12-23
  • 2021-08-11
  • 2021-05-23
  • 2022-12-23
  • 2021-09-25
  • 2022-12-23
  • 2022-01-14
猜你喜欢
  • 2021-08-10
  • 2021-06-15
  • 2021-09-29
  • 2022-02-08
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案