从命令行操作的实践来谈重构的修炼
重构之前:寻找出哪些部分应该被重构
重构对旧有的代码影响就是:一部分代码需要被摒弃、被改造、被重组。上一节我们说了应该吸纳旧有代码的“精华”,而这一节,我们则要“剥离不良代码”。
ApplicationManager命令行类中有一些不错的设计思路,当然也有一些令人遗憾的结构。
(1)虽然分离出任务这个概念,但是参数的解析却是共享的。
每个任务会有自己一些特定的参数,有些参数是共同的,而有些参数是私有的。那么旧有的命令行类是如何实现的呢?
private String mDomain; |
是的,旧有的命令行类,讲所有的参数都定义在成命令行类的属性。如果你需要新增一个任务,而与这个任务有关联的参数就必须新增一些属性。
(2)每增加一个参数定义,就需要增加一段“if else”代码片段来parse参数。事实上,任务的参数解析是可以被抽象的。
让我们看看旧有的命令行在解析这些参数的代码实现片段:
|
很显然,当然新增了任务,或新增了参数之后,你不得不在这里再次修改代码片段。
(3)每个任务又是由很多参数组成的。每个参数都有共性,那么就可以进行“抽象的验证”。各个参数的组合验证,则又组成了一个任务的“抽象的验证”。
但是,旧有的命令行类是如何实现的呢?
|
(4)每增加一个任务,不得不在新增一个usage方法,并写上一些“累赘”的帮助资料。而这些usage是可以依赖任务所持有的参数而固定的。
(5)······(还有其他一些个人觉得不妥的地方,不在这里一一叙述了)
这些应该被重构的地方,就是你最初应该重构所需要达到的目标。当然,可能这时候,你会有一些新的feature希望实现,那么也可以纳入你的重构目标中。
重构的误区:避免过度重构和设计
很多人,在重构的时候,一不小心就走入了“繁杂”的误区。寻求“扩展性”必然会令支撑的代码结构变的复杂,但是不能因为一些“可能的扩展性”而盲目的设计,把重构的目标一味的放大。这样过度的重构和设计,反而会让“重构之旅夭折在路上”
比如这个ApplicationManager命令行类,已经分解成:任务+参数。但是,在最初的设计意图和实现中,任务都是“并列”的。deploy和upload这是两个任务,这两个任务是完全并列的。
但是在现实中,命令行处理的复杂性,很容易就会出现下面的情况:
ApplicationManager –flatten –export -xxx
ApplicationManager –flatten –revert –xxx
可以看到,Flatten这个任务下面又产生了“两个独立的任务”。
是不是据此我们就有必要为任务增加一个“子任务”的概念呢?—— 这个想法并没有任何错误。但是对于“开始重构”这个阶段,过度的“考虑”是“兵家大忌”的。过度的考虑和设计,只能让你自己变的更加迷惘,对重构却没有任何好处。可以看看上面那些需要重构的部分吧,已经很多了。
而且,分析一下旧有的那些任务,只有一两个任务的参数会稍微复杂一些。也就是说这种“子任务”的设计并没有多少价值。即使遇到这种情况,在任务处理类中,简单的“if else”就可以很容易处理。
开始重构了:先简单构思一下你的设计。