如何修复基本上没有结构的项目?


25

我从事一个软件项目(主要是单独工作)已有5年以上。首先是一团糟(我是从事此工作的第三或第四位开发人员),尽管现在已不再是一团糟,但它仍然杂乱无章。使它得到控制的进展速度令人不寒而栗,我开始对它所处的状态感到沮丧。我如何真正开始修复它?

项目细节:这是一个销售程序,几乎完全用Visual Basic Classic(VB6)编写,带有MySQL后端和用C#编写的报表引擎。C#报表模块非常有趣,它只是在过去的几年中编写的,而在此之前所有报表都是在Crystal Reports 9中完成的(是的,我们仍然有一些报表依赖于此)。

但是,实际程序本身就是一场彻底的灾难。总的LOC数不足9万,注释约有1万行(大多数不是文档,而是注释掉的旧代码)。158个表单文件和80个模块文件。我不知道实际使用了多少个,因为程序的某些功能被简单地弃用了(有时是这样),而没有从程序中删除相关的代码。我猜想只有50%的代码可以实际用于生产。

我害怕触碰很多代码,只是因为我不确定我是否正在破坏一个晦涩的客户所依赖的东西,这种情况发生的次数超出了我的估计。就像整个代码中散布着地雷一样。

该项目实际上没有任何结构。到目前为止,除了在我耐心改革的几个地方之外,它不是面向对象的。如果需要在表单上获取数据,则可以实例化数据库对象,然后在函数中声明查询,然后执行查询并对数据集执行操作。

当我开始从事该项目时,没有使用任何源代码控制。我试图鼓励其他正在使用它的人使用它,但是我是新手,试图让人们使用Subversion的尝试全部失败了。该公司的首席开发人员在过去的几年中终于发现了一个软错误,并且他确保所有开发人员现在确实在所有项目上使用了源代码控制,因此至少可以取得一些进展。

我认为,如果我能够全职进行该项目的改革,我将能够取得不错的进展,甚至可以估算出我完成整个项目所需的时间,但是该项目正在积极使用中,我经常被要求扑灭火灾,修复错误,添加功能等。

那么,我如何开始真正解决这个问题呢?尝试使用其他语言来工具VB6吗?尝试在业余时间重写程序吗?还是这完全没有希望?

更新资料

这篇文章发表后,我怀着新的热情回到了这个项目,但是在看到如此缓慢的进展之后,在几个月内又陷入了绝望。然后,在接下来的一年左右的时间里,我又重复了此循环2到3次。

从那以后,我转到了另一份工作。尽管经过了很多年的vb6,并且只有其他技术的外围经验,但是搜索仍然很困难,而且我在此过程中遇到了很多拒绝(一年中约十二次采访)。在这种情况下,我对他人的建议是考虑单独考虑这一因素。考虑保持这样的死胡同对您的职业可能造成的损害。


4
听起来很糟糕。首先是要保存当前代码的副本,并删除已注释掉的旧代码(这只是噪音)。当我在旧系统上工作时,通常会在代码的顶部放一个日期,然后将其注释掉。然后删除注释掉了6个月或更久的代码。
程序员

4
我将从贾米森开始,然后一直努力。。。
怀亚特·巴内特

1
您是否曾经尝试接管VB程序员编写的C#项目?
שינתיאאבישגנת

Answers:


28

现在它已在源代码管理中,您可以摆脱注释掉的代码。

我从类似的情况开始(80KLOC VB6应用程序,没有源代码控制,没有真实的结构,几乎所有事情都在事件处理程序中完成)。

在大约2年的时间里,我已经有超过一半的人转换为C#(通常在需要重要的新功能时)。所有新的C#代码都有单元测试范围。当然,转换为C#肯定需要更多时间。如果您不添加重要的新模块,那么我不会走这条路。

我要做的一件事是创建一个基本的数据访问层,该层从数据库自动生成。至少在表列名称更改时遇到了问题,而我没有在代码中找到所有位置。另外,我已经将业务逻辑从表单事件处理程序中缓慢地移到了模块中。

但是,我的优势在于该应用程序仅是内部的。由于我只有一个要部署的站点,因此承担的风险可能会比您大。如果我犯了一个错误,通常解决它并不重要。听起来你没有那么奢侈。

我真的认为您最好的选择是采用以下方法:

  1. 详细了解每一个细节。这使您不太可能无意间破坏某些内容。
  2. 毫不留情地进行重构以改善分离和结构,但是不要试图在其中尝试新的方法,例如面向对象的编程,因为VB6对此很烂。
  3. 将其视为学习经验。如果您从未见过劣质的方法,您怎么会知道另一种更好的方法呢?
  4. 除非您有主要的写作模块,否则不要以新的语言/框架/平台来重写。即使这样,也要仔细考虑。

请记住,该计划的目标是成为使您的公司赚钱的产品。它不必是艺术的一个完美的工作(我是个完美主义所以它真的很难,我承认)。有时候,最好还是接受实用主义。

据推测,那里有很多COBOL程序员维护着大量的遗留代码。我怀疑他们都在疯狂地努力用某种新语言重写它。:)


3
+1好答案:我要补充的是,确保您对自己的期望不高。与新开发的代码,旧代码相比,代码维护速度较慢,甚至您描述的速度也较慢,而且没有文档化,非结构化代码。...最近5年,我从事各种代码基础的工作,其始于1980年代, SLOC ...我知道你的痛苦...
mattnz

+1,但是一个OO功能VB6在接口处可以正常运行。如果您看到几次粘贴类似代码的代码被复制并粘贴了几次,那么即使不是完整的类,也可以在接口中进行重构。
马克·赫德2012年

3

您需要做的就是重构。在没有单元测试的情况下,重构几乎是不可能的,因为没有单元测试可以使您确信自己没有破坏任何东西。因此,从创建单元测试开始。记录代码的行为-而不是(仅)记录在纸上,而在更多代码中,记录单元测试。一旦完成测试,就可以开始重组代码。


11
我一直处于这种情况。首先,VB6具有可怜的单元测试套件。其次,单元测试几乎总是需要DI,而在VB6中这确实很困难,因为它对面向对象编程的支持很差。我还没有听到任何人参加过VB6项目,编写了一堆单元测试并进行重构狂潮,即使这是您经常在Programmers.SE上遇到类似问题的答案。您是否知道为表单事件处理程序中各处嵌入的逻辑编写单元测试是多么痛苦?你必须重构之前,你可以写检查!
Scott Whitlock,2012年

我很想在我们的代码中添加单元测试,但是对于从哪里开始我一无所知。我已经使用.net和其他语言进行了一些单元测试,但仅仅是从头开始,从未将测试添加到现有项目中。而且我做过的任何单元测试都没有在使用GUI的程序上进行,特别是没有在事件处理程序中混合了很多数据库和业务逻辑的GUI!
迪伦·尼斯斯利

1
如果代码没有被编写成可测试的,那么您所要做的就是编写单元测试,该测试涵盖了简单明显的情况,而错过了导致90%缺陷的边缘情况。我去过那里,这样做浪费了很多时间和精力(读金钱)。最好的方法是确保您更改的代码易于测试-在您所拥有的环境中这意味着什么,这听起来不像是单元测试。
mattnz

3

大卫·阿根(David Agan)的“ 调试 ”中的一条规则浮现在脑海:停止思考和观察。您碰巧拥有一台能够处理大量文本的机器。使用它可以准确地找出不再使用的代码,并毫不留情地删除它。如果您输入有误,这就是源代码管理的目的。

那是容易的部分。接下来您需要考虑的是如何吃一头大象?一次咬一口。拿起马丁·福勒(Martin Fowler)的“ 重构 ”,逐个函数接一个文件地处理它。不要完全废弃某些东西,并根据您的需求对其进行重写。像登山者一样工作,在下一个安全装置到位之前,切勿卸下先前的安全装置。

有足够的隐喻吗?关键是,如果让它缓慢而稳定地进行,并进行许多改进,例如重命名或拆分功能,则可以改进代码的不良部分,而不会破坏通过多年调试和功能请求而建立的优良部分。 。您希望代码始终保持可交付状态。如果有可能在移植到更现代的语言时做到这一点,那就去吧。


除非做得好,否则“移植到现代语言”将给出“ C#语法的VB程序”-当前正在移植到真正是“ Cava”而非Java的Java应用程序的C语言-两者都是最糟糕的,而且两者都不是最好的........正确地移植实际上是对阻力的重写,并且正如乔尔所说的那样-在“不可做的事情”列表上非常重要。
mattnz

好点子。这就是为什么我说“如果可能的话”。如果您不能一点一点地做,而且还习惯性地编写移植的代码,则不要尝试。
Karl Bielefeldt 2012年

3

我不想这么说,但是我会继续“无休止的修补/增强”循环,并希望“一切都没有希望”。我已经看到太多的VB6项目(如您描述的项目),并且试图将它们重构/重写/重做到C#/。NET中的尝试非常失败,通常是由负责这种尝试的人来完成的。

问题是迟早需要彻底重新编写。很好地支持它的VB6和Windows版本正在下降。找到知道VB6怪癖并愿意从事此类程序工作的开发人员变得越来越少。VB6的内部限制将在类似这样的大型程序上发生,从而导致奇怪的错误。

如果此时大家对总体,重新设计,重新设计和重写有良好的共识和承诺,请开始进行工作并将正在进行的维护工作委托给其他人(承包商,初级程序员,无论您做什么)。如果人们还没有足够的信心说服他们开始这样做,那就等着痛苦变得足够大,否则就转向更绿色的牧场。


+1您对VB6在现代Windows版本上失去支持是正确的。或早或晚(可能更快),您的应用程序将仅在需要的地方停止运行。
伯纳德

1

这里已经有一些不错的答案,我想补充一件事。不必尝试重写所有内容,也许您将有机会将至少大部分这些模块(主要是1:1)移植到VB.NET(当然,这样做时您必须非常小心)?根据我的经验,与尝试从头开始重建所有现有功能相比,可以以大约5-10倍的工作量完成这种移植。移植之后,便可以开始进行重构-使用.NET世界中所有可用的工具,例如好的单元测试工具,自动重构工具,真实的OOP等。

我曾经遇到过类似的情况,当时我们不得不将旧的16位C ++程序(150k LOC)迁移到32位世界中,在此世界中不再使用原始的GUI框架。我们花了一些时间才知道重写是不现实的,但是在我们决定使用C ++,C ++ / CLI和C#将其移植到.NET世界之后,我们只需要大约9个月的时间就可以实现这一目标(大约需要1个开发人员全职从事该项目)。而且我们没有可用的GUI部件单元测试,而是手动完成了所有这些部件的测试。


0

尽管它非常重视对应用程序进行单元测试,尽管这是非常重要的事情,但是在VB6中却很难做到,但史蒂文·麦康奈尔(Steven McConnell)写了一本很棒的书,讲述了如何解决这样的问题。

看一看:

Steven C. MCCONNELL:有效处理旧版代码,第二版。Microsoft出版社,2004年6月。

基本上,他的观点是每次慢慢一点。他还建议从一开始就使用不太可能破坏任何东西的重构技术,有时在短期内使它变得更糟,并开始使用更高级的技术,因为代码将变得更加简洁并具有单元测试来支持它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.