大话重构连载:遗留系统——软件工业时代的痛

我经常感到幸运,我们如今所处的是一个令人振奋的时代,我们进入了软件工业时代。在这个时代里,我们进行软件开发已经不再是一个一个的小作坊,我们在进行着集团化的大规模开发。我们开发的软件不再是为某个车间、某个工序设计的辅助工具。它从某个单位走向整个集团,走向整个行业,甚至整个社会,发挥着越来越关键的数据。一套软件所起到的作用与影响有多大。已经远远超越了全部人的想象。成为一个地区、一个社会。乃至整个国家不可或缺的组成部分。

慢慢地,人们已经难以想象没有某某软件或系统的生活和工作会是如何的。这就是软件工业时代的重要时代特征。

然而,在这个令人振奋的软件工业时代,处于时代中心的各大软件企业却令人沮丧。软件规模越来越庞大,软件结构越来越复杂的同一时候,却是软件质量越来越低下,软件维护变得越来越困难,以至于每一个小小的变更都变得须要伤筋动骨。

研发人员为此举足无措。測试人员成为唯一的救星,每一个小小的变更都须要付出巨大代价进行測试。软件企业在这样一种恶性循环中苦苦支撑。毫无疑问。这也成为这个令人振奋的时代的还有一个特征。

是的,面对软件工业时代我们并没有做好准备。过去,一套软件的生命周期只是2~3年时间。随着软件需求的变化。我们总是选择将软件推倒了又一次开发。可是如今这种情况在发生着改变。

随着软件规模的扩大。软件数据的积累,软件影响力的提升,我们,以及我们的客户。都真切地感受到,要推倒一套软件又一次开发,将变得越来越困难而不切实际。这种结果就是,我们的软件将不停地改动、维护、再改动、再维护……直到永远。

这是一件多么痛苦的事情啊!

一套软件,当它第一次被开发出来的时候,一切都十分清晰:清晰的业务需求、清晰的设计思路、清晰的程序代码。但经历了几次需求变更与维护以后,一切就变得不那么清晰了。业务需求文档变得模糊不清。设计思路已经跟不上变更的脚步,程序代码则随着业务逻辑的复杂而臃肿不堪。程序猿開始读不懂代码,软件开发工作变得不再是一种乐趣。

随着时间的推移,软件经过数年、数十次的变更与维护,情况变得越来越糟。最初的程序猿已经不愿再看到自己的代码而选择离去。他的继任者们变得更无所是从。因为看不懂程序,代码的每一次改动如同在走钢丝。

測试人员变成了唯一的希望,开发者的每一次改动都意味着測试人员须要把全部程序測试一遍。继任者们開始质问最初的设计者们。程序是怎么设计的。假设此时恰巧又有什么新技术出现,就会更显得原有系统的破旧与不堪。

相信这就是软件工业时代的全部企业都不得不面对的尴尬境界。难倒真的是我们最初的设计错了吗?是的,我们都这样质问过我们自己,因此我们開始尝试在软件设计之初投入很多其它的精力。

我们開始投入很多其它的时间作需求调研。考虑很多其它可能的需求变化。做很多其它的接口,实现更加灵活但复杂的设计。

然后呢,我们攻克了我们的问题了吗?显然是没有。需求并没有像我们想象的那样发生变更:我们之前觉得可能发生的变更并没有发生,使我们为之做出的设计变成了摆设;我们之前没有考虑到的变更发生了。让我们猝不及防,软件质量開始下降,我们被打回了原形。难倒真的是无药可解了吗?在我看来,假设我们没有看明确软件开发的规律与特点。那么我们永远找不到那份向往已久的解药。

如今,让我们真正静下心来分析分析软件开发的规律与特点吧。

软件。特别是管理软件,事实上质是对真实世界的模拟。我们通过对真实世界的模拟。实现计算机的信息化管理。来提高我们的生产效率。然而,真实的世界复杂而多变的,我们认识世界却是一个由简单到复杂循序渐进的过程,这是一个我们无法改变的客观规律。因此,毫无疑问,遵循着这样一个客观规律,我们的软件开发过程必定也是一个由简单到复杂循序渐进的过程。

最初。我们开发的是一个对真实世界最简单、最主要、最核心部分的模拟。由于简单,我们的思路变得清晰而明了。

可是。我们的软件不能永远仅仅是模拟那些最简单、最主要、最核心的部分。我们的客户在使用软件的过程中,假设遇到那些不那么简单、不那么主要、不那么核心的情况时,我们的软件就无法处理了,这是客户不管怎样不能接受的。因此,但软件的第一个版本号交付客户以后,客户的需求就開始变更。

客户的需求永远不会脱离真实世界,也就是说。真实世界不存在的事物、现象、关系永远都不可能出如今软件需求中。可是。真实世界的事物、规则与联系并非那么的简单与清晰的。随着我们的软件对它模拟得越来越仔细,程序的业务逻辑開始变得不再那么清晰而易于理解。这就是软件质量下降最关键的内因。

不论什么一个软件的设计,总是与软件的复杂度有密切的关系。

举例来说吧,客户资料是很多系统都必需要记录的重要信息。起初,我们程序简单,客户资料只记录了一些简单的信息,如客户名称、地址、电话等等,但随着程序复杂度的添加,客户资料開始变得复杂。

比方,起初“地址”字段就只需要一个字符串就能够了。但随着需求的变更。它開始有了省份、城市、地区、街道等信息。随后还会有邮政编码、所属社区、派出所等信息。

起初添加一个两个字段时我们还能够在“客户信息表”里凑合一下。但后来我们必需要及时调整我们的设计,将地址提取出来单独形成一个“地址信息表”。假设不及时予以调整,“客户信息表”将越来越臃肿。由10来个字段,变成50个、80个、上100个……

信息表尚且如此,业务操作更是如此。起初的业务操作是如此的简单而明了,以至于我们不须要花费太多的类就能够将它们描写叙述清楚。比方开票操作,最初的需求就是将已开具的票据信息读取出来,保存,并统计出本月开票量及金额。

这样一个简单操作,设计成一个简单的“开票业务类”合情合理。但随后的业务逻辑变得越来越复杂,我们要检查客户是否存在、开票人是否有权限、票据是否还有库存。等等。

起初的开票方式仅仅有一种,但随着非正常开票的添加,开票方式不再单一,而统计方式也随之变化……随着业务的不断添加,软件代码的规模也在发生着质的变化。假设这时我们不及时调整我们的设计,而是将全部的程序都硬塞进“开票业务类”,那么程序质量必定会退化。“开票业务类”由原有的数十行,激增到数百行,甚至上千行。

这时的代码将难于阅读,维护它将变成一种痛苦。毫无乐趣可言。

面对这种状况,我们应当如何走出困境呢?毫无疑问。就是重构,软件的重构。开票前的校验真的属于“开票业务类”吗?它们是否应当被提取出来,解耦成一个一个的校验类。正常开票与非正常开票真的应该写在一起吗?是否我们应当把“开票业务类”抽象成接口。以及正常开票与非正常开票的实现类。

这就是我给大家的良方:当软件由于需求变更而開始渐渐退化时,运用软件重构改善我们的结构。使之又一次适应软件需求的变化。

大话重构连载首页:http://blog.csdn.net/mooodo/article/details/32083021

特别说明:希望网友们在转载本文时,应当注明作者或出处,以示对作者的尊重,谢谢。


posted on 2017-05-02 08:50  wgwyanfs  阅读(115)  评论(0编辑  收藏  举报

导航