重构代码:什么时候做什么?
自从我开始使用.NET以来,我一直在创建Helper类或者Partial类,以将代码定位并包含在它们自己的小容器中,等等。
我想知道的是使代码尽可能干净和优美的最佳实践。
显然,干净的代码是主观的,但是我说的是何时使用东西(而不是如何使用它们),例如多态性,继承,接口,类以及如何更恰当地设计类(使它们更有用,而不仅仅是说" DatabaseHelper',就像有人认为代码中的这种不良做法会散发出Wiki一样)。
是否有任何资源可以帮助此类决策?
请记住,我什至还没有开始过CS或者软件工程课程,而且教学资源在现实生活中是相当有限的。
解决方案
查看Martin Fowler的评论,并预订有关重构的书。
这是一本名为"清洁代码"的书中斜线的评论。
这本书显然有点干,但是非常好。
让我真正大开眼界的是重构:改进现有代码的设计:
With proper training a skilled system designer can take a bad design and rework it into well-designed, robust code. In this book, Martin Fowler shows you where opportunities for refactoring typically can be found, and how to go about reworking a bad design into a good one.
重构http://ecx.images-amazon.com/images/I/519XT0DER6L.SL160_PIlitb-dp-arrow,TopRight,21,-23_SH30_OU01_AA115.jpg
它帮助我高效,系统地重构代码。当其他开发人员的"神圣代码"必须更改时,它也帮助我与其他开发人员进行了很多讨论。
杰夫·阿特伍德(Jeff Atwood)撰写了一篇有关重构和代码味道的不错的博客文章,我们可能想检查一下。
.NET中的重构代码需要花费一些时间。我们需要了解一些面向对象的设计原则(或者设计技术),以便有效,毫不留情地进行重构。
简而言之,我们可以重构代码以消除代码异味,并使更改更容易进行。另外,不要过度使用它。
- 当代码引起问题时,请对其进行重构。任何问题都会发生:性能,可扩展性,集成性,维护性-任何使我们在应有的时间上花费更多时间的问题。它没有损坏,即使我们不相信它是干净的或者不符合现代标准,也请不要对其进行修复。
- 不要花太多时间使代码完美。我们将永远无法达到完美,但我们可能会花费大量时间来尝试做到这一点。记住收益递减的规律。
- 在项目内部,只有在实际使用依赖于它的功能时,才需要重构代码。 IE。如果我们有迭代的用户案例,则需要"更改上传机制"或者"修复文件上传中的错误",则可以重构文件上传代码。但是,如果用户故事是关于"翻新文件上传UI设计"的,那么请不要考虑业务逻辑。
我建议域驱动设计。我认为YAGNI和AlwaysRefactor原则都是两个简单化。关于该问题的古老问题是我是否将" if(someArgument == someValue)"重构为一个函数或者将其内联?
没有是或者否的答案。如果测试代表商务规则,DDD建议对其进行重构。重构不仅(仅)与重用有关,还与使意图明确有关。
有效地使用旧版代码是我所见过的关于此主题的最好的书之一。
不要拖延这本书的标题,而不是将重构作为一个正式的概念(有它的位置),这本书有很多简单的"我为什么没有想到"的技巧。诸如"遍历一类并删除未直接实现到该类的任何方法并将它们置于不同的方法之类的事情"之类的事情。
例如我们有一个网格和一些代码来将该网格的布局持久保存到文件中。我们可能可以安全地将持久化布局的代码移到另一个类中。
我刚得到一份"代码完成"的副本,发现其中有一部分。
尽管我仍将阅读被接受的答案的书,但是Code Complete教给我的东西大大改善了我设计类的方式。
在今天之前,我不知道什么是ADT(抽象数据类型),现在我知道如何开发遵守封装的类。
在http://www.refactoring.com/上有一个致力于重构的网页。它具有许多关于重构代码主题的参考资料,以及讨论重构相关问题的邮件列表。
最后但并非最不重要的一点是,有大量的(且仍在不断增长的)重构目录,其范围远远超出了Martin Fowler在(非常推荐的)重构书中所写的内容。
我的经验法则是使代码的形状不会比我们发现的糟糕。
我们的想法是朝着更好的方向努力,而不是试图达到完美的结果,或者一直走下去。
个别重构有时会带来可疑的好处,作为一个极端的例子,如果m_Pi是比m_PI更好的名称,则可能确实存在争议。但是,即使没有明显的"更好",多数情况下,一种选择更为一致,也就不足为奇了。
我经常发现自己会自动重构的一种情况是在代码段上实现功能之前。
经常有一些待办事项待办事项,一些不一致之处,或者有时是自定义功能,这些功能最近已经获得了更好的库支持。在实现实际功能请求之前进行这些更改可以使我对代码有所了解,并且可以验证"之前"功能。
还有一点是在修复错误之后。之后,因此pre-repro不会受到影响,并且错误修复和重构是两个单独的提交。