Ano*_*ous 4 language-agnostic refactoring
我很难尝试用许多分支重构一些代码片段.有许多if/then/else块,其中一些是嵌套的.
是否有任何技巧可用于重构代码而不浪费大量时间试图首先理解功能的每个次要方面?
现在我基本上使用布尔代数(De Morgan定律).我正在尝试修改if语句中的条件,因此我可以在if/then/else块之外弹出小代码片段.这有点帮助,但代码仍然是分支的.我知道,在某些时候我最终还是要打破BIGGIES成更小的类的方法,但由于代码包含许多其他类方法的调用,并有很多本地范围变量的这是复杂的,所以我将不得不应对传球新方法的许多论据.我想知道在开始将它分成不同的小块(类方法)之前,我是否可以使用其他一些技巧来提高代码质量.
tpd*_*pdi 14
根据我的经验,在进入分支和等效的逻辑表达式之前,在功能上分解(将事物分解为做一件事并做得好的较小函数)几乎总是更有效率.
没有浪费大量时间试图首先理解功能的每个次要方面?
除此之外,功能分解的行为将导致您理解代码的作用,从而导致进一步分解的机会.您希望获得仅包含少量参数的函数,并返回no,一个或几个值.
通过分解,您将更好地理解哪些部分在算法上是必不可少的(必须以这种方式做到正确)以及哪些部分仅仅是实现细节(必须完成,但可以以各种不同的方式完成,而无需改变输出).
通常情况下,您会发现许多深度嵌套的ifs是不必要的,或者是冗余重复的,或者足够相似,如果您在其他重复的代码中分解出微小的差异,它们可以简化为一个或几个函数.
换句话说,您希望获得的句柄不是代码的细节,而是代码处理的抽象事物.许多问题归结为一些数据结构(列表,队列,树,集)和该结构上的一些操作.在某种程度上,您可以分离数据结构和算法,您可以获得简化事物的抽象级别.或者你可以发现,无论你需要做什么都更适合其他结构或算法,然后你可以吹走很多东西.
我记得几年前一位同事总是编写数据库游标,做任何事情,因为这就是他知道该怎么做.设置和拆除游标需要一些样板,以及一个带有错误检查的循环,因此他的代码看起来总是看起来很复杂.他会在存储过程中执行此操作,当然会添加更多样板文件.
现在,正如它发生的那样,这是在Sybase T-SQL中,它有一个全局的错误和一个全局的游标状态,两次都检查两次,一次是他拿到第一个游标行,然后是一次循环迭代所有其他行.并且他一直把错误变量(@@error)与游标状态变量混淆(@@sqlstatus成功时为零(得到游标行),失败时为1,如果游标中没有更多行,则为2).他的代码在名义路径上工作,因为如果他已经排成一行,两者都是零,当他试图在最后一行之后获得该行时,他会得到一个错误.所以,如果仔细观察他的代码,你会再次呻吟!(并再次!)并为他解决这个问题.
但是接下来你会仔细观察,看到他正在通过所有行的集合where x = 1和每一行设置进行游戏y = y * 2,你最终会告诉他,"只需写一个更新声明!".
你纠正他的全局变量,虽然正确,但没有解决真正的问题,即当他刚刚从客户端代码发送更新语句时,他正在使用游标和存储过程没有充分理由.
确定输出更难,因为不仅仅是查看全局变量的局部使用,你必须看两个地方:光标被声明(declare cursor_foo cursor for select * from table where x = 1 for update;)的地方和更新发生的地方有20行(update table set y = y * 2 where current of cursor_foo).(而且所有这些都是以非常模板化的方式进行多线化的.)
弄清楚它也比较困难,因为你只是假设没有人会经历所有这些只是为了做更新; 当然所有这些样板都必须是因为更新中发生了一些特殊的事情,对吧?或者因为where谓词是动态的还是什么?所以你看看这个,并且是一个尊重他的同事的谦虚的编码员,你的第一直觉是," 我在这里缺少什么,必须有一个使用光标的原因?"
(尽管我和他的老板都在解释@@ error和@@ sqlstatus之间的区别,但他从来没有得到它,更不用说他几乎总能做到这一点的想法update;他认为在程序代码方面,从来没有"得到过"数据库,尽管作为"数据库程序员"具有表面经验.)
我们的教训是,在你确认首先需要细节(实施细节)之前,不要陷入细节.通过首先分解代码,您可以更好地理解正在处理的抽象,并真正改进代码.