Refactoring-Improving the Design of Existing Code——学习笔记(1)
《重构,改善既有代码的设计》是Martin Fowler所写,作者具有丰富的软件实践经验,总结出代码重构的一些规则与方法。重构能够极大地提高代码质量,至少能够提高可读性,对于现在的编程,效率已经不是主要考虑方面,而是面向人的代码,一个优秀的代码首先要能够简洁易读,而不是杂乱的、不可接受的。对于我来说,虽然没有什么软件工程实践,然而通过阅读《重构》,对于能够写出有质量的代码提供借鉴意义。
Chapter 6 Composing Methods
(1)Extract Method
You have a codefragment that can be grouped together. Turn the fragment into a method whosename explains the purpose of the method.
例子:
void printOwing(double amount) {
printBanner();
//print details
System.out.println(“name:” + _name);
System.out.println(“amount:”+amount);
}
重构后:
void printOwing(double amount) {
printBanner();
printDetails(amount);
}
void printDetails(double amount) {
System.out.println(“name:”+_name);
System.out.println(“amount:”+amount);
}
思考:记得曾经看过一本《编写简洁代码》的书,其中提到应该尽量减少注释,多利用函数名代替注释。这里就是一个很好的例子,用一个额外的函数代替注释,虽然看起来代码多了一些,然而确实要相对简洁,并且提高了一定的扩展性。当然,是否这样的修改对于自己合适,那就要合理的分析了。
(2)Inline Method
A method’s bodyis just as clear as its name. Put the method’s body into the body of itscallers and remove the method.
例子:
int getRating() {
return (moreThanFivelateDeliveries()) ? 2: 1;
}
Boolean moreThanFiveLateDeliveries() {
return _numberOfLateDeliveries > 5;
}
重构后:
int getRating() {
return (_numbreOfLateDeliveries > 5) ? 2 : 1;
}
思考:修改后的代码看起来比较简洁,逻辑更加清晰,不需要通过读很长的函数名就能够明白意思。运用之妙在于一心。
(3)Inline Temp
You have a tempthat is assigned to once with a simple expression, and the temp is getting inthe way of other refactorings.
例子:
double basePrice = anOrder.basePrice();
return (basePrice > 1000);
重构后:
return (anOrder.basePrice() > 1000);
(4)Replace Temp with Query
You are using atemporary variable to hold the result of an expression. Extract the expressioninto a method. Replace all references to the temp with the new method. The new methodcan then be used in other methods.
double basePrice = _quantity * _itemPrice;
if (basePrice > 1000)
return basePrice * 0.95;
else
return basePrice * 0.98;
重构后:
if (basePrice() > 1000)
return basePrice() * 0.95;
else
return basePrice() * 0.98;
double basePrice() {
return _quantity * _itemPrice;
}
(5)Introduce Explaining Variable
You have acomplicated expression. Put the result of the expression, or parts of theexpression, in a temporary variable with a name that explains the purpose.
例子:
if ( (platform.toUpperCase().indexOf(“MAC”) > -1) &&
(browser.toUpperCase().indexOf(“IE”) > -1) &&
wasInitialized() && resize > 0)
{
//do something
}
重构后:
final boolean isMacOs = platform.toUpperCase().indexOf(“MAC”) > -1;
final Boolean isIEBrower = browser.toUpperCase().indexOf(“IE”) > -1;
final Boolean wasResized = resize > 0;
if (isMacOS && isIEBrowser && wasInitialized() && wasResized) {
//do something
}
思考:这样的修改增强了可读性,虽然引进了一些变量。
(6)Split Temporary Variable
You have atemporary variable assigned to more than once, but is not a loop variable nor acollecting temporary variable. Make a separate temporary variable for eachassignment.
例子:
double temp = 2 * (_height + _width);
System.out.println(temp);
temp = _height * _width;
System.out.println(temp);
重构后:
final double perimeter = 2 * (_height+_width);
System.out.println(perimeter);
final double area = _height * _width;
System.out.println(area);
思考:变量的名字很重要的说。
(7)Remove Assignments to Parameters
The code assignsto a parameter. Use a temporary variable instead.
int discount (int inputVal, int quantity, int yearToDate) {
if(inputVal > 50) inputVal -= 2;
}
重构后:
int discount (int inputVal, int quantity, int yearToDate) {
int result = inputVal;
if(inputVal > 50) result -= 2;
}
(8)Replace Method with Method Object
You have a longmethod that uses local variables in such a way that you cannot apply ExtratMethod. Turn the method into its own object so that all the local variablesbecome fields on that object. You can then decompose the method into othermethods on the same object.
(9)Substitute Algorithm
You want toreplace an algorithm with one that is clearer. Replace the body of the methodwith the new algorithm.
String foundPerson(String[] people) {
for(int i=0;i<people.length;i++) {
if(people[i].equals(“Don”)) {
return “Don”;
}
if(people[i].equals(“John”)){
return “John”;
}
if(people[i].equals(“Kent”)){
return “Kent”;
}
}
return “”;
}
重构后:
String foundPerson(String[] people) {
List candidates = Arrays.asList(new String[] {“Don”,”John”,”Kent”});
for(int i=0;i<people.length;i++)
if(candidates.contains(people[i]))
return people[i];
return “”;
}