Refactoring
重构
Refactoring is closely related to factoring, or what is now referred to as using design patterns. Design Patterns: Elements of Reusable Object-Oriented Software, by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, provides the foundational work on design patterns. Design Patterns serves modern-day OO programmers much as Larry Constantine and Ed Yourdon's Structural Design served a previous generation; it provides guidelines for program structures that are more effective than other program structures.
重构(Refactoring)与构造 (factoring),或者说与设计模式的使用密切相关。Erich Gamma, Richard Helm, Ralph Johnson, 和 John Vlissides合著的《 Design Patterns: Elements of Reusable Object-Oriented 》一书为设计模式做出了奠基性的工作。正如Larry Constantine 和Ed Yourdon 所倡导的结构化设计一样,设计模式对当代的面向对象技术程序设计做出了巨大的贡献,为开发人员带来了福音。通过设计模式,程序的结构的比以往更为有效。 If Figure 4 shows the correct balance of designing versus refactoring for environments experiencing high rates of change, then the quality of initial design remains extremely important. Design patterns provide the means for improving the quality of initial designs by offering models that have proven effective in the past.
如果图表4 所显示的设计(designing)与重构(refactoring)在面对高速变化环境时的适应能力方面的差别是客观的话,初始设计的质量则显的尤为重要。通过提供过去已被证明是有效的模式,设计模式(Design patterns)提供了一种提高初始设计质量的方法。
So, you might ask, why a separate refactoring book? Can't we just use the design patterns in redesign? Yes and no. As all developers (and their managers) understand, messing with existing code can be a ticklish proposition. The cliché "if it ain't broke, don't fix it" lives on in annals of development folklore. However, as Fowler comments, "The program may not be broken, but it does hurt." Fear of breaking some part of the code base that's "working" actually hastens the degradation of that code base. However, Fowler is well aware of the concern: "Before I do the refactoring, I need to figure out how to do it safely.... I've written down the safe steps in the catalog." Fowler's book, Refactoring: Improving the Design of Existing Code, catalogs not only the before (poor code) and after (better code based on patterns), but also the steps required to migrate from one to the other. These migration steps reduce the chances of introducing defects during the refactoring effort.
现在,也许你会问,为什么还需要一本独立讲重构的书呢?难道我们不可以只使用设计模式来重新设计吗?可以,也不可以。正如所有的开发人员(包括管理者)都知道,修改原有的程序代码是一件棘手的事。development folklore年刊上有一句话,"if it ain't broke,don't fix it".然而,正如Fowler所提到的,"程序也许还没有'坏掉',但却造成了潜在的危害." 害怕对那些还能"工作"的代码重新构造实际上只会加剧代码性能的衰退。同时,Fowler也清楚的认识到:"在软件重构之前,需要找到安全的做法……我把这些安全的步骤写进了目录"。Fowler所写的<>,不仅编录了如何对以前的(差的)代码和以后的(基于模式设计的较好)的代码进行重构的方法,而且也包含了代码分割重构的步骤。这些步骤减少了在重构过程中出现差错的机会。
Beck describes his "two-hat" approach to refactoring -- namely that adding new functionality and refactoring are two different activities. Refactoring, per se, doesn't change the observable behavior of the software; it enhances the internal structure. When new functionality needs to be added, the first step is often to refactor in order to simplify the addition of new functionality. This new functionality that is proposed, in fact, should provide the impetus to refactor.
Beck用"two-hat"方法来描述重构,也就是说, 添加新的功能与重构是两种不同的行为。在本质上,重构不改变软件可见的外部功能,它只是增强了软件的内部结构。当有新的功能需要添加时,第一步常是对软件进行重构,使添加更简化。事实上,这种添加的新功能为重构提供着推动力。
Refactoring might be thought of as incremental, as opposed to monumental, redesign. "Without refactoring, the design of the program will decay," Fowler writes. "Loss of structure has a cumulative effect." Historically, our approach to maintenance has been "quick and dirty," so even in those cases where good initial design work was done, it degraded over time.
与重量级的再设计相反,重构可以被认为是增量(incremental)式的再设计,"没有重构,程序设计会 腐烂",Fowler写到," 结构性的缺陷会带来累积效应 "。历史上,我们对软件维护的方法是"quick and dirty"(快速但不彻底的?),致使一些初始设计工作做的好的项目,随着时间推移,也会"退化"(degrade).
Figure 5 -- Software entropy over time.
Figure 5 shows the impact of neglected refactoring -- at some point, the cost of enhancements becomes prohibitive because the software is so shaky. At this point, monumental redesign (or replacement) becomes the only option, and these are usually high- risk, or at least high-cost, projects. Figure 5 also shows that while in the 1980s software decay might have taken a decade, the rate of change today hastens the decay. For example, many client- server applications hurriedly built in the early 1990s are now more costly to maintain than mainframe legacy applications built in the 1980s.
图表 5 显示了没有重构时的情况:因为软件是如此的不可靠,升级维护费用变的让人望而却步,于是巨型(monumental)设计(或替换)成了唯一选择,项目的风险,至少是投入上,变的越来越大。图 5也显示,在80年代,软件的生存期大约要10年,而在今天需求的快速变化加剧了软件的腐烂。举个例子,许多90年代初一窝蜂做出来的C/S应用软件在今天比80年代留下来的大型机软件的维护费用还要高的多。
Data Refactoring: Comments by Ken Orr
数据重构: Ken Orr注解
Editor's Note: As I mentioned above, one thing I like about XP and refactoring proponents is that they are clear about the boundary conditions for which they consider their ideas applicable. For example, Fowler has an entire chapter titled "Problems with Refactoring." Database refactoring tops Fowler's list. Fowler's target, as stated in the subtitle to his book, is to improve code. So, for data, I turn to someone who has been thinking about data refactoring for a long time (although not using that specific term). The following section on data refactoring was written by Ken Orr.
编者注: 如上所提,XP和重构思想吸引我的一点是他们能够清楚认识到所要考虑实施问题的边界条件(boundary conditions).例如,Fowler写了一章"Problems with Refactoring".其中首要的问题就是数据库的重构。正如书的副标题所示,Fowler的目标是为了提高代码质量。为此,我咨询了一些在数据重构(或者用其他的术语)方面有较深研究的人。以下关于数据重构部分由Ken Orr所写。
When Jim asked me to put together something on refactoring, I had to ask him what that really meant. It seemed to me to come down to a couple of very simple ideas:
当Jim 要我讲一讲重构时,我问他重构究竟意味着什么。对我来说,把它归纳为以下简单的几点:
Do what you know how to do.
做你会做的
Do it quickly.
速战速决
When changes occur, go back and redesign them in.
当发生变化时,回过头来重新设计
Go to 1.
回到 1
Over the years, Jim and I have worked together on a variety of systems methodologies, all of which were consistent with the refactoring philosophy. Back in the 1970s, we created a methodology built on data structures. The idea was that if you knew what people wanted, you could work backward and design a database that would give you just the data that you needed, and from there you could determine just what inputs you needed to update the database so that you could produce the output required.
在过去几年中,Jim和我一起工作,共同研究各种系统方法学(systems methodologies),发现所有的方法学与重构思想(refactoring philosophy)有着一致的地方。70年代,我们建立了一种基于数据结构的方法学。其主要思想是:在知道了人们的需求后,逆向工作,设计一个仅含必需数据的数据库,然后再确定更新数据库必需的输入数据,产生需要的输出数据。
Creating systems by working backward from outputs to database to inputs proved to be a very effective and efficient means of developing systems. This methodology was developed at about the same time that relational databases were coming into vogue, and we could show that our approach would always create a well-behaved, normalized database. More than that, however, was the idea that approaching systems this way created minimal systems. In fact, one of our customers actually used this methodology to rebuild a system that was already in place. The customer started with the outputs and worked backward to design a minimal database with minimal input requirements.
从输出结果逆向工程到数据库再到输入来建构系统的方法被证明是一种非常有效和有效率的系统开发方法。几乎在关系数据库开始流行的同时,这种方法也发展了起来。使我们能够建立起运作良好,规范化的数据库。除此之外,这种思想也适用于创建最小系统(minimal systems).事实上,我们的一个客户在重建一个系统时已经使用了这种方法并取得了成功。该客户从输出入手,通过逆向工程设计了一个满足最小输入需求的最小数据库。
The new system had only about one-third the data elements of the system it was replacing. This was a major breakthrough. These developers came to understand that creating minimal systems had enormous advantages: they were much smaller and therefore much faster to implement, and they were also easier to understand and change, since everything had a purpose.
新系统只有老系统三分之一的数据元(data elements )。这是一个大的突破。开发人员开始逐渐认识到建立最小系统有着巨大的优势:系统更小因而可以更快的实现;功能单一更能适应变化。
Still, building minimal systems goes against the grain of many analysts and programmers, who pride themselves on thinking ahead and anticipating future needs, no matter how remote. I think this attitude stems from the difficulty that programmers have had with maintenance. Maintaining large systems has been so difficult and fraught with problems that many analysts and programmers would rather spend enormous effort at the front end of the systems development cycle, so they don't have to maintain the system ever again. But as history shows, this approach of guessing about the future never works out. No matter how clever we are in thinking ahead, some new, unanticipated requirement comes up to bite us. (How many people included Internet-based e-business as one of their top requirements in systems they were building 10 years ago?)
然而,创建最小系统并不符合许多分析员和程序员们的想法,不管有多遥远,他们总认为自己可以超前思考并预见到未来的需求。我认为这源于软件难于维护的原因。维护一个大的系统是如此的困难并充斥着问题,以致于许多分析员和程序员宁愿在系统开发的前期花费大量的精力来设计一个"完善"的系统,以求一劳永逸。然而事实证明,预测未来是徒劳的。不论我们有多聪明,思想有多超前,总会有一些不曾预料到的需求出现。(有多少人能够在10年前就将基于internet的电子商务作为未来的需求写入自己的软件)
Ultimately, one of the reasons that maintenance is so difficult revolves around the problem of changing the database design. In most developers' eyes, once you design a database and start to program against it, it is almost impossible to change that database design. In a way, the database design is something like the foundation of the system: once you have poured concrete for the foundation, there is almost no way you can go back and change it. As it turns out, major changes to databases in large systems happen very infrequently, only when they are unavoidable. People simply do not think about redesigning a database as a normal part of systems maintenance, and, as a consequence, major changes are often unbelievably difficult.
最后,维护如此困难的原因之一在于,当改变数据库设计时,其他的问题都会接踵而来。在大多数开发人员看来,一旦设计好数据库并在此基础上开始了编码以后,再去改变数据库的设计几乎是不可能的。在某种程度上,设计数据库就好比建造系统的地基:一旦你把混凝土灌了进去,你就没办法再去改变它。因此,除非不可避免,大型系统中的数据库极少会发生大的改动。人们不能把重新设计数据库仅仅当成系统维护的普通一部分。否则的话,对系统进行大的改动会变的难以想象的困难。
Enter Data Refactoring
进入数据重构
Jim and I had never been persuaded by the argument that the database design could never be changed once installed. We had the idea that if you wanted to have a minimal system, then it was necessary to take changes or new requirements to the system and repeat the basic system cycle over again, reintegrating these new requirements with the original requirements to create a new system. You could say that what we were doing was data refactoring, although we never called it that.
Jim和我永远都不会承认一旦系统开始运行就不能再改变数据库设计的观点.我们认为,如果你想使系统保持最精简的状态,就必须要把所要做的变化或新的功能引入到系统中并重复基本的开发过程,使新的需求和旧的需求融合在一起而成为一个新的系统.你可能会说我们所作的就是数据重构,可我们从来不那么说.
The advantages of this approach turned out to be significant. For one thing, there was no major difference between development of a new system and the maintenance or major modification of an existing one. This meant that training and project management could be simplified considerably. It also meant that our systems tended not to degrade over time, since we "built in" changes rather than "adding them on" to the existing system.
这么做的好处是显而易见的.首先,开发一个新系统和维护或对旧系统统进行较大改造的区别并不是很大.这就意味着管理一个项目和培训工作将大大减少.同时,也将减少开发时间,这是因为我们对变化的处理方式不同,一个是'built in'(建立在变化之上),另一个是'adding them on'(添加变化)。
Over a period of years, we built a methodology (Data Structured Systems Development or Warnier/Orr) and trained thousands of systems analysts and programmers. The process that we developed was largely manual, although we thought that if we built a detailed-enough methodology, it should be possible to automate large pieces of that methodology in CASE tools.
在过去的几年里,我们建立了一种方法(结构化系统设计方法或Warnier-Orr法)并且培训了数以千计的系统分析员和编程人员。即便我们在定义了足够详细的各种说明后有可能用CASE工具实现大部分工作,但开发过程仍需要大量的手工工作。
Automating Data Refactoring
自动化的数据重构
To make the story short, a group of systems developers in South America finally accomplished the automation of our data refactoring approach in the late 1980s. A company led by Breogán Gonda and Nicolás Jodal created a tool called GeneXus1 that accomplished what we had conceived in the 1970s. They created an approach in which you could enter data structures for input screens; with those data structures, GeneXus automatically designed a normalized database and generated the code to navigate, update, and report against that database.
为了缩短开发时间,南美的一组系统开发人员在80年代年开发出了数据重构自动化工具。由Breogán Gonda 和 Nicolás Jodal领导的公司开发了一种名叫GeneXus的工具,这正是我们在70年代所构想要的。他们创建的方法使我们在输入数据结构以后,系统能够自动为你创建规范的数据库并产生浏览、更新和输出数据的代码。
But that was the easy part. They designed their tool in such a way that when requirements changed or users came up with something new or different, they could restate their requirements, rerun (recompile), and GeneXus would redesign the database, convert the previous database automatically to the new design, and then regenerate just those programs that were affected by the changes in the database design. They created a closed-loop refactoring cycle based on data requirements.
这就使事情简单了,这种工具使得当用户的需求或系统的要求改变后只需要修改原有的定义,重新编译,就能够重新设计数据库以适应新的需求,并产生仅仅受数据库修改影响而需要改变的代码。这就是基于数据的闭环的重构过程。
GeneXus showed us what was really possible using a refactoring framework. For the first time in my experience, developers were freed from having to worry about future requirements. It allowed them to define just what they knew and then rapidly build a system that did just what they had defined. Then, when (not if) the requirements changed, they could simply reenter those changes, recompile the system, and they had a new, completely integrated, minimal system that incorporated the new requirements.
GeneXus使我们认识到重构能构给我们带来的真正的东西。就我的经验而言,这使开发人员从对未来需求的担忧中解脱出来,从而能够使开发人员仅仅定义他们所知道的并快速的实现所定义的所有内容。因此,当系统的需求更改以后,他们只须简单的加入那些修改,重新编译,就可以得到一个新的、完全集成的、满足新的需求的最小系统。
What Does All This Mean?
所有的这一切意味着什么?
Refactoring is becoming something of a buzzword. And like all buzzwords, there is some good news and some bad news. The good news is that, when implemented correctly, refactoring makes it possible for us to build very robust systems very rapidly. The bad news is that we have to rethink how we go about developing systems. Many of our most cherished project management and development strategies need to be rethought. We have to become very conscious of interactive, incremental design. We have to be much more willing to prototype our way to success and to use tools that will do complex parts of the systems development process (database design and code generation) for us.
重构正在逐渐变成一个时髦的词语。与所有的时髦的东西一样,既有好的一面,也有坏的一面。好的一面是:如果能够正确的实施,重构使我们有可能快速构建健壮的系统。坏的一方面是:我们不得不重新考虑如何进行开发。原先采用的所有开发和管理策略需要重新考虑。我们必须了解交互式的、增量的开发方法;我们还必须习惯于使我们能够成功的模式化的开发方法和使用工具来完成系统开发工作中那些复杂的工作(数据库设计和代码生成)。
In the 1980s, CASE was a technology that was somehow going to revolutionize programming. In the 1990s, objects and OO development were going to do the same. Neither of these technologies lived up to their early expectations. But today, tools like GeneXus really do many of the things that the system gurus of the 1980s anticipated. It is possible, currently, to take a set of requirements, automatically design a database from those requirements, generate an operational database from among the number of commercially available relational databases (Oracle, DB2, Informix, MS SQL Server, and Access), and generate code (prototype and production) that will navigate, update, and report against those databases in a variety of different languages (COBOL, RPG, C, C++, and Java). Moreover, it will do this at very high speed.
80年代,CASE使开发产生革命性的变化。90年代,对象和OO方法也使开发产生革命性的变化。这些技术都没有像达到期望的效果。但现在,像GeneXus这样的工具切切实实的做到了80年代人们所期望的东西。确实有可能在给定系统需求后自动进行数据库设计,生成一种实际工作的商用关系型数据库(Oracle, DB2, Informix, MS SQL Server, and Access),并产生能够浏览、更新和输出数据库中数据的不同语言(COBOL, RPG, C, C++, and Java)的代码(原型和结果)。
This new approach to systems development allows us to spend much more time with users, exploring their requirements and giving them user interface choices that were never possible when we were building things at arm's length. But not everybody appreciates this new world. For one thing, it takes a great deal of the mystery out of the process. For another, it puts much more stress on rapid development.
新的系统开发方法能够使我们有更多的时间和用户交流,分析用户的需求,让用户选择不同的交互界面,这在只凭自己来完成所有事情的时侯是不可能的。但是并不是所有人都喜欢这一开发方法。一个是因为这将很大程度上拨开开发过程的神秘面纱。另一个是因为这也给快速开发增加了压力。
When people tell you that building simple, minimal systems is out of date in this Internet age, tell them that the Internet is all about speed and service. Tell them that refactoring is not just the best way to build the kind of systems that we need for the 21st century, it is the only way.
当人们告诉你在Internet时代已经不可能再建立简单、精简的系统的时侯,那么告诉他们Internet是速度和服务的天下,告诉他们重构不仅仅是在21世纪建立这样系统的最好方法,也是唯一的方法。
-------------------------------------------------------------------------------
NOTES
1Gonda and Jodal created a company called ARTech to market the GeneXus product. It currently has more than 3,000 customers worldwide and is marketed in the US by GeneXus, Inc.
文章来源于领测软件测试网 https://www.ltesting.net/