【敏捷软件开发:原则、模式与实践】之代码重构
来源:互联网 发布:qt linux sleep头文件 编辑:程序博客网 时间:2024/04/25 21:56
一 概念
在Martin Fowler的名著《重构》中,他把重构定义为:在不改变代码外在行为的前提下对代码进行修改,以改进代码的内部结构的过程。
代码实现了需求,但是代码却不精炼,冗余,结构混乱,难读懂,难维护,难扩展等等。与之相对应的一个词是"refactor",即代码重构。我们在看些外国人写的程序时可以发现,他们的代码里一般会定义大量的类、接口、方法,类与类,类与接口之间很多是继承和实现的关系,方法的代码行数很少,超过20行代码的方法不多,看他们的代码感觉最多的就是方法之间的调来调去,不像我们的代码,一个方法下来几十上百甚至两三百行都是最基本的语句构成,很少调用自己的方法。两相比较,可以看出,前者在结构上更清晰,通过类视图就可看出设计意图,并且总的代码量不会高于后者,而后者代码量庞大,代码冗余现象严重,结构不清晰,很难维护,如要修改某个错误,可能涉及到要修改的代码点很多,这样后来的维护者就很头疼了。造成这种状况的原因有这样一些:
1.经验不足,分析设计不到位
2.敏捷开发,虽然经验很多,但为了快速开发,没有经过分析设计
3.缺乏意识,只为实现功能而写代码,不管代码质量
对于这样的代码,我们怎样将其变得更为精炼和易于维护呢?这就是代码重构。重构不是针对功能,纯粹是对代码本身。重构后的代码不会影响到系统的运行。
我们来看看可以在哪些方面对代码进行重构:
1.重命名:对类,接口,方法,属性等重命名,以使得更易理解
2.抽取代码:将方法内的一段代码抽取为另一个方法,以使得该段代码可以被其他方法调用,这是重构中很重要很常用的,此举可以极大的精炼代码,减少方法的代码行数
3.封装字段:将类的某个字段转换成属性,可以更加合理的控制字段的访问
4.抽取接口:将类的某些属性,方法抽取组成个接口,该类自动实现该接口
5.提升方法内的局部变量为方法的参数:这主要是在写代码的过程中会使用到
6.删除参数:将方法的一个或多个参数删掉
7.重排参数:将方法的参数顺序重新排列
实际应用中,用的最多的是1、2、3,我们可以在写代码的时候有意识的运用代码重构,这样当我们完成编码时代码的质量也能得到保证。
/** * This class Generates prime numbers up to a user specified maximum. * the algorithm used is the Sieve of Eratosthenes. * <p> * Eratosthenes of Cyrene, b. c. 276 BC, Cyrene, Libya -- * d. c. 194, Alexandria. The first man to calculate the circumference * of the Earth. Also known for working on calendars with leap * years and ran the library at Alexandria. * <p> * The algorithm is quite simple. Given an array of integers starting * at 2. Cross out all multiples of 2. Find the next uncrossed * integer, and cross out all of its multiples. Repeat until * you have passed the square root of the maximum value. * * @author Robert C. Martin * @version 9 Dec 1999 rcm */import java.util.*;/** * Class declaration * * * @author Robert C. Martin * @version %I%, %G% */public class GeneratePrimes{ /** * @param maxValue is the generation limit. */ public static int[] generatePrimes(int maxValue) { if (maxValue >= 2) // the only valid case { // declarations int s = maxValue + 1; // size of array boolean[] f = new boolean[s]; int i; // initialize array to true. for (i = 0; i < s; i++) f[i] = true; // get rid of known non-primes f[0] = f[1] = false; // sieve int j; for (i = 2; i < Math.sqrt(s) + 1; i++) { for (j = 2 * i; j < s; j += i) f[j] = false; // multiple is not prime } // how many primes are there? int count = 0; for (i = 0; i < s; i++) { if (f[i]) count++; // bump count. } int[] primes = new int[count]; // move the primes into the result for (i = 0, j = 0; i < s; i++) { if (f[i]) // if prime primes[j++] = i; } return primes; // return the primes } else // maxValue < 2 return new int[0]; // return null array if bad input. }}
/** * This class Generates prime numbers up to a user specified * maximum. The algorithm used is the Sieve of Eratosthenes. * Given an array of integers starting at 2: * Find the first uncrossed integer, and cross out all its * multiples. Repeat until there are no more multiples * in the array. */public class PrimeGenerator{ private static boolean[] crossedOut; private static int[] result; public static int[] generatePrimes(int maxValue) { if (maxValue < 2) return new int[0]; else { uncrossIntegersUpTo(maxValue); crossOutMultiples(); putUncrossedIntegersIntoResult(); return result; } } private static void uncrossIntegersUpTo(int maxValue) { crossedOut = new boolean[maxValue + 1]; for (int i = 2; i < crossedOut.length; i++) crossedOut[i] = false; } private static void crossOutMultiples() { int limit = determineIterationLimit(); for (int i = 2; i <= limit; i++) if (notCrossed(i)) crossOutMultiplesOf(i); } private static int determineIterationLimit() { // Every multiple in the array has a prime factor that // is less than or equal to the root of the array size, // so we don't have to cross of multiples of numbers // larger than that root. double iterationLimit = Math.sqrt(crossedOut.length); return (int) iterationLimit; } private static void crossOutMultiplesOf(int i) { for (int multiple = 2*i; multiple < crossedOut.length; multiple += i) crossedOut[multiple] = true; } private static boolean notCrossed(int i) { return crossedOut[i] == false; } private static void putUncrossedIntegersIntoResult() { result = new int[numberOfUncrossedIntegers()]; for (int j = 0, i = 2; i < crossedOut.length; i++) if (notCrossed(i)) result[j++] = i; } private static int numberOfUncrossedIntegers() { int count = 0; for (int i = 2; i < crossedOut.length; i++) if (notCrossed(i)) count++; return count; }}
- 【敏捷软件开发:原则、模式与实践】之代码重构
- 【敏捷软件开发:原则、模式与实践】之敏捷实践
- 敏捷软件开发:原则模式与实践之笔记
- 【敏捷软件开发:原则、模式与实践】之敏捷设计的几个原则
- 《敏捷软件开发:原则、模式与实践》--敏捷开发读书笔记
- 《敏捷软件开发 原则、模式与实践》的读书笔记
- 敏捷软件开发(原则,模式与实践)笔记1
- 敏捷软件开发(原则,模式与实践)
- 敏捷软件开发(原则,模式与实践)笔记1
- 《敏捷软件开发原则、模式与实践》读书笔记(一)
- 敏捷软件开发:原则、模式与实践的学习笔记
- 好书共享:《敏捷软件开发:原则、模式与实践》
- 《敏捷软件开发(原则、模式与实践)》前三章笔记
- 推荐:《敏捷软件开发、原则、模式与实践》电子版
- 读后感--敏捷软件开发:原则、模式与实践
- 敏捷软件开发原则,模式与实践书摘
- 敏捷软件开发-原则、模式与实践 (一)
- 《敏捷软件开发:原则 模式与实践》笔记 未完。。
- linux下ffmpeg的使用方法
- JQuery如何判断标签指定属性是否存在
- C++循环顺序队列
- Linux系统强大的控制台、终端和shell的关系
- Offer被拒后,张一鸣决定跟技术人才聊聊,你的下一份工作应该在哪里
- 【敏捷软件开发:原则、模式与实践】之代码重构
- [IOS]PDF阅读
- uva 1304 - Art Gallery(半平面相交)
- CentOS 7 下安装 Redis 2.8.7
- XML example with RESTEasy + JAXB
- js要入门?
- OGG安装配置文档
- Android studio中正确引入so文件的方法
- python文件中的__name__=='__main__'的使用及调用其他py文件中的函数方法