首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何为重写应用程序的胶水做准备

如何为重写应用程序的胶水做准备
EN

Software Engineering用户
提问于 2014-02-27 11:14:57
回答 3查看 1.5K关注 0票数 5

假设您有一个项目(在您看来)编写得很好,模块化,等等,并且您希望保留它的大部分功能。然而,这个项目的一个重要部分没有很好的设计,而且很难用小的改动来修复。修复它的唯一方法是删除大量代码;它并不是那么糟糕,您需要(或应该)从头开始,但它非常普遍。

假设代码大约是20,000行非空格、非单一的大括号、不注释的Java、C++、C#、PHP或Ruby代码。您估计大约2000-3000行需要抛出或更改。在类似于Java或C#的情况下,您的包/名称空间可能会完全从头开始重写,而且对这些类的许多引用都会发生变化。

下面是具有挑战性的部分:需要更改的代码是系统中的粘合剂。这里有一张非常简单的图片,总结了这个问题:

这就是我所处的情况,导致了这个问题:当我在提交之间等待太久时,我该怎么办?

正如您所看到的,不仅仅是代码的各个部分在执行内部处理,还包括与系统其他部分通信的部分。API和内部数据结构都是不够的。试图使这两组API都可以用于增量更改,这将是令人遗憾的冗余。

当然,我在做任何事情之前都做了分支,但是我所做的每一次改变都产生了一个根本不起作用的产品。在许多情况下,我创建了编译错误。这导致我不断推迟提交,因为我想“是的,我把这些片段连接起来,但是我仍然需要实现这个新的接口,编写这个基本的功能,等等。”这导致了我没有检查任何东西的罪过,如果我再次陷入这种情况,我宁愿不要重复这个错误。我的所有API都是内部的,除了我必须遵守外部世界和第三方模块的API之外,这一点得到了缓解,但是我对这些部分的包装正在改变。

一个明显的替代解决方案是接受这样一个事实,即每一次更改都会导致整个产品的损坏,但是既然您正在签入一个分支,就可以了。特别是因为我是处理这段代码并使用这些API的唯一开发人员。所以也许这是正确的做法。或者,也许正确的做法是尝试首先将API重构到新的API,而不实际更改功能(如果可能的话),即使某些参数是虚拟的,或者最终会被删除,然后增量的更改就会更自我包含。还是有更好的办法呢?

EN

回答 3

Software Engineering用户

发布于 2014-02-27 14:14:36

简单地说:不要把海洋煮沸

换句话说,切断一些小的、可管理的块,而不是一次完成整个任务。在一个分支里。没有定期检查。

我一直喜欢这篇文章发表在Joel on上软件。它给出了非常好的具体例子,说明了可以针对代码库进行的小更改,以使代码逐渐变得更干净。

决定一个概念上相似的更改块,并为此创建一个分支。一个示例可能是将所有SQL代码移动到类中。在该分支中,您的工作流程如下所示:

  • 删除一条SQL语句
  • 做测试
  • 签入您的代码
  • 重复

一旦完成了这些更改,就将其合并到主分支中,并启动一个新的块。

这是假设你有测试。如果没有,您应该在开始之前创建它们(包括单元、回归和集成测试)。再说一遍,不是一次全部。如果您想重构一个没有测试的函数,那么编写测试,重构代码并运行测试,直到测试通过为止。这正是这些测试的目的所在。确保你在利用它们。

票数 8
EN

Software Engineering用户

发布于 2014-02-27 14:13:50

重要的是要知道您的产品是否已经发布,以及您想要接触的API是否以任何方式公开给单独发布的其他实体(模块、项目、产品、文档等)。如果其中任何一个答案都是“是”,则必须在过渡阶段保持API兼容性。与其取代旧的API,不如扩展它。在第二步中,您可以淘汰旧的API并给受影响的实体一个更新的机会。如果可以验证所有相关实体都已停止使用旧API,则只有这样才能将其从您的侧移除。(即使您没有外部依赖项,它仍然可以帮助您使用相同的方法进行重写)。

尽管如此,进行重大重写的一个好方法是尽可能多地将工作划分为较小的独立步骤。

很容易陷入同时处理多个目的的陷阱,但通常会以这样或那样的方式纠缠您的提交--最好的情况是,您必须跟踪多个分支和进展中的特性,这些特性需要在某个时候合并;最糟糕的情况是,所有新特性都是相互交织开发的,防止您对属于单个特性的提交进行清理,甚至阻止您进行任何提交,因为您始终拥有一半工作或不编译的特性。它还将“帮助”您介绍各种模糊的交互错误,在试图找到引入bug的确切位置时会给您带来很多麻烦。

这在很大程度上是一种心理训练,而且有不止一种方法。您可以从突出新API并记录预期用途和API细节开始。一旦完成,您就有了一个稳定的提交点。然后,您可以着手实现单个特性和单元测试(并且可以在此过程中多次提交)。最后,修改调用新API的模块,并完成所有“胶水”工作。此命令将帮助您在不破坏构建的情况下拥有可以提交的停止点。

再说一次,这只是一种方式,而不是唯一的方法。您的目的是模块化重写和最小化更改之间的交互。

票数 2
EN

Software Engineering用户

发布于 2014-02-27 14:40:50

我参与过不止一次有针对性的重写。在开始编写更多代码之前,您需要做一些分析:

  • 设计得好和设计不好的零件有什么不同?
  • 设计糟糕的代码是否可以与好代码的设计结构相匹配?
  • 识别设计不良的代码的所有触点。即调用什么方法,如何调用它们(即对象实例或单例,等等)
  • 这些触点中有多少是你能安全消除的?
  • 确定您可以用来将坏代码与好代码隔离开来的任何接口。

从所有的原始数据来看,你的最终结果应该是什么样的呢?您需要知道什么时候完成,或者什么时候重写足够好给您一个高质量的产品,而不需要放弃每一行代码。

  • 把工作分解成任务,你可以一次完成一个任务。
  • 估计每项任务需要多长时间。如果你真的不能给出一个好的估计,那么这个任务可能需要更多的细分。包括用于自动化和/或单元测试的时间。
  • 把你认为要完成的每一项任务的时间加起来,并把它增加三倍。我是认真的。会有隐藏的后果,你的重新设计,你没有办法在这一点上预期。
  • 将您的活动限制在目标重写范围内。您没有时间使用新特性,也没有时间处理代码的其他部分。
  • 一次只执行一个任务。在继续工作之前,确保每个任务都已完成并经过测试。

我可以说,经过我的有针对性的重写经验,很多次,最终的产品是更好和更容易维护,但时间表是最大的问题。如果你有有限的时间来完成这项工作,重写会使你的项目比你最初想象的要晚很多。

票数 2
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/230666

复制
相关文章
水平滚动条
主要用到并排Div 的父级设置white-space: nowrap,并排的div设置display:inline-block;
tianyawhl
2019/07/16
2.6K0
[iOS] WSHorizontalPickerView 图片水平滚动封装
之前这篇文章传送门本来是记录自己练手的demo的,后来很多人来问我要代码。今天就抽时间封装了一下,没有考虑太多情况,等我有空再去仔细考虑吧。
wOw
2018/09/18
3K0
WPF 让 TextBox 支持水平滚动
超级简单的方法,只需要设置 HorizontalScrollBarVisibility 可见就可以了
林德熙
2022/08/12
9850
CSS——多列
多列属性可以将文本设计成像报纸杂志那种多列排版的布局,类似于Microsoft Word中的段落分栏功能。
Html5知典
2019/11/26
1.3K0
pandas dataframe 新增单列和多列
dataframe assign方法,返回一个新对象(副本),不影响旧dataframe对象
lovelife110
2021/01/14
4.5K0
表单水平文字滚动,效果还有阴影
加菲猫的VFP
2023/08/21
2720
表单水平文字滚动,效果还有阴影
自定义View实现水平滚动控件
      前几天项目中需要使用到一个水平可滚动的选择条,类似下图效果(图片是从简书上一位作者那儿找来的,本篇也是在这位作者的文章的基础上修改的,站在大神的肩膀上,哈哈,由于原文没有提供demo,而且
coderZhen
2018/06/28
9410
jQuery无缝图片横向(水平)/竖向(垂直)滚动
jQuery的一个不错的小插件,记性越来越差了,整理一下贴在这里,方便以后Copy & Paste <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title> </title> <script typ
菩提树下的杨过
2018/01/22
17.4K0
有意思的水平横向溢出滚动
最近接到一个很有意思的需求,能否做到当内容横向溢出时,依然能够使用鼠标滚轮对内容进行滚动的方法。
Sb_Coco
2022/09/28
2.6K0
有意思的水平横向溢出滚动
excel 多列内容拼接
例如想要拼接  A2 和 B2 的内容生成一个新列,A2 内容为 320,B2 内容为 480,我们生成新列,需要拼接两列内容,中间同时拼接 * ,新列公式如下:
蓓蕾心晴
2022/10/27
1.5K0
联合索引(多列索引)[通俗易懂]
联合索引是指对表上的多个列进行索引,联合索引也是一棵B+树,不同的是联合索引的键值数量不是1,而是大于等于2.
全栈程序员站长
2022/09/05
2.7K0
如何纯CSS实现标题栏、表格头水平滚动垂直不滚动
有些报表会很宽,浏览器水平放不下,需要水平滚动显示,这个可以设置overflow-y:hidden实现,很基本的实现,没什么难度。
周陆军博客
2023/05/07
1.7K0
JqGrid实现超长水平(左右)滚动条功能
使用JqGrid来实现列表功能非常方便快捷,但在使用的过程中还会遇到一些定制化的问题。这篇文章来跟大家说一下当列表中数据比较多时,如何实现水平(左右)滚动来确保能够查看完整的信息。
程序新视界
2020/05/18
3.9K0
MFC 控件编程之水平滚动条跟垂直滚动条
  首先在操作滚动条的时候.我们要知道滚动条的一些属性. 比如我们要设置 最大值 最小值. 以及每次递增的值是多少.都要设置.
IBinary
2019/05/25
2.9K0
MySQL索引中的前缀索引和多列索引
正确地创建和使用索引是实现高性能查询的基础,本文笔者介绍MySQL中的前缀索引和多列索引。
玖柒的小窝
2021/11/06
4.7K0
点击加载更多

相似问题

水平滚动的多列问题

21

列和水平滚动

12

有多列的页面,水平滚动,没有垂直滚动

22

具有水平滚动和自动列宽和高度的多列CSS列表

36

具有水平滚动和图像的自动多列固定高度问题

13
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档