refactoring - 什么时候(如果有的话)废弃生产代码并重新开始?

标签 refactoring

就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the help center为指导。




9年前关闭。




我被要求进行代码审查并报告向我们的一个新产品添加新功能的可行性,我直到现在还没有亲自参与过。我知道挑剔别人的代码很容易,但我会说它的状态很糟糕(同时尽量保持客观)。我的代码审查中的一些亮点:

  • 线程滥用: QueueUserWorkItem和线程通常被大量使用,线程池委托(delegate)具有无信息名称,例如 PoolStartPoolStart2 .线程之间也缺乏适当的同步,特别是访问 UI 线程以外的线程上的 UI 对象。
  • 魔术数字和魔术字符串 : 一些 Const的和 Enum 's 在代码中定义,但大部分代码依赖于文字值。
  • 全局变量 :许多变量被声明为全局变量,可能会或可能不会被初始化,具体取决于遵循的代码路径和事物发生的顺序。当代码也在线程之间跳转时,这会变得非常困惑。
  • 编译器警告 : 主要解决方案文件包含500+警告,总数我不知道。我收到来自 Visual Studio 的警告,说它无法再显示任何警告。
  • 半成品类 : 代码已经完成并添加到这里和那里,我认为这导致人们忘记了他们以前做过的事情,所以有一些看似半成品的类和空的 stub 。
  • 不是在这里发明的 :该产品复制了其他产品使用的公共(public)库中已经存在的功能,例如数据访问助手、错误记录助手和用户界面助手。
  • 关注点分离 :我认为有人在读到典型的“UI -> 业务层 -> 数据访问层”3 层架构时,把这本书颠倒了。在这个代码库中,UI层直接访问数据库,因为业务层被部分实现但由于不够充分而被忽略,数据访问层控制UI层。大多数低级数据库和网络方法都对主窗体的全局引用进行操作,直接显示、隐藏和修改窗体。在实际使用相当薄的业务层的地方,它也倾向于直接控制 UI。大多数低级代码也使用 MessageBox.Show出现异常时显示错误信息,大部分吞下原来的异常。这当然会使在尝试重构之前开始编写单元测试以验证程序的功能变得更加复杂。

  • 我只是触及了表面,但我的问题很简单:花时间重构现有代码库,一次只关注一个问题,还是考虑从头开始重写整个事情更有意义?

    编辑 :澄清一下,我们确实有项目的原始要求,这就是为什么重新开始可能是一种选择。表达我的问题的另一种方式是:代码是否可以达到这样的程度,即维护它的成本会变得大于丢弃它并重新开始的成本?

    最佳答案

    在没有任何冒犯的情况下,从头开始重写代码库的决定是新手软件开发人员经常犯的严重管理错误。

    有许多缺点需要警惕。

  • 重写会阻止新功能在数月/数年内被冷开发。很少有公司能够承受如此长时间的停滞不前。
  • 大多数开发计划都很难确定。这次重写也不异常(exception)。现在,通过延迟开发来放大前一点。
  • 通过痛苦的经历在现有代码库中修复的错误将被重新引入。 Joel Spolsky 在 this article 中有更多例子.
  • 成为 Second-system effect 受害者的危险-- 总而言之,``那些只设计过一次的人尝试做他们“上次没有做的”的所有事情,将他们在制作第一版时推迟的所有事情加载到项目中,甚至如果他们中的大多数也应该在第二版中推迟。''
  • 一旦完成了这种昂贵、繁重的重写,下一个继承新代码库的团队很可能会使用相同的借口进行另一次重写。程序员讨厌学习别人的代码。没有人会写出完美的代码,因为完美是如此主观。找我任何现实世界的应用程序,我可以给你一个该死的控诉和从头开始重写的理由。

  • 无论您最终是否从头开始重写,现在开始重构阶段都是真正坐下来理解问题的好方法,这样如果真正需要,重写就会更顺利,同时让现有代码库看起来更真实真正看看是否需要重写。

    关于refactoring - 什么时候(如果有的话)废弃生产代码并重新开始?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/144734/

    相关文章:

    refactoring - 重构函数以使其可在 Go 中跨类型重用

    c# - 在 VS2008 中用花括号 {} 包围代码块的任何方法?

    refactoring - UML 时间可视化

    javascript - 我如何优化这一长行 "if"语句?

    javascript - ASP.NET重构思路: TypeScript

    c# - Ctrl+R,Ctrl+R 命令不起作用

    iphone - ObjC+Cocoa 中的回调

    java - 通用使用 2 个相同的类但来自不同的包

    haskell - 添加操作而不更改结果以重构 do-notation

    c++ - 语法繁重的多个 lambda 包装器的替代方案——如何避免样板代码?