2015年2月1日 星期日

重構概念

重構(refactoring)
指不改變外部所見的程式行為的前提下,將程式內部的結構進行改善。

主要兩點:
1.即使執行了重構,亦不會改變外部所見的程式行為。
2.一旦執行了重構,程式內部的結構將會改善。

執行三步驟:
1.在重構前先進行測試。
2.進行重構。
3.在重構之後再度進行測試。

重構的限制:
1.程式還不能執行的情況。
2.時間緊迫的情況。

不祥的徵兆:
1.難以理解。
2.難以修改。
3.難以擴張。

例如:重複的程式碼、冗長的方法、過多的引數、變更的分散、公開方法過多...等。

不祥的徵兆6個口訣:
1.重複了。
2.太長了。
3.太多了。
4.名不符其實。
5.公開太多了。
6.不太像是物件導向。


重構的本質:
Step by Step
1.非同時進行兩個修改。
2.為了易於回復。
3.以Step為單位的確認。
4.由舊換新。


=====================================================================
<用符號常數取代Magic Number>
1.Magic Number-用符號常數取代Magic Number
例如:
在程式碼中寫下了100,這數字代表了什麼無法立即得知。
可是如果將100換成了 MAX_INPUT_LENGTH 可大幅增加程式的可讀性。

問題:
Magic Number的意義難以了解。
Magic Number寫在多個地方時難以修改。

解決:
使用符號常數來取代 Magic Number。


但有時像
for(int i = 0 ; i < buffer.length ; i++){...} (O)
就不用在刻意去改成
for(int i = 0 ; i < BUFFER_SIZE ; i++){...} (X)

2.用class來取代Type Code
TypeCode是指為了區別事務而分配的數值的意思。

範例程式:
public class RobotCommand {
 private final String _name;
 public RobotCommand(String name) {
  _name = name;
 }
}

public static final RobotCommand COMMAND_WALK = new RobotCommand("WALK");
public static final RobotCommand COMMAND_STOP = new RobotCommand("STOP");
public static final RobotCommand COMMAND_JUMP = new RobotCommand("JUMP");

public void order(RobotCommand command) {
 if(command == COMMAND_WALK) {
 } else if(command == COMMAND_STOP) {
 } else if(command == COMMAND_JUMP) {
 } else {...}
}

3.使用enum

public Robot {

 public enum Command {
  WALK,STOP,JUMP
 }

 public void order(Robot.Command command) {
  if(command == COMMAND.WALK) {
  } else if(command == COMMAND.STOP) {
  } else if(command == COMMAND.JUMP) {
  } else {...}
 }

}


=====================================================================

<控制旗標(flag)的移除>

旗標(flag):
用來記錄狀態並控制處裡流程的boolean型態的變數。

問題:
處理流程是被控制旗標所控制著,程式碼會變得更複雜。

解決:
用break、continue、return來取代控制旗標來控制流程。