1.Rename Method 重新命名函式
函式的名稱未能清楚表達該用途
getPhoneNumber()
getOfficeTelephoneNumber()
2.Add Parameter 添加參數
原因:某個函式需要從呼叫端得到更多資訊
getContact()
getContact(:Date)
3.Remove Parameter 移除參數
當你發現函式本體不再需要用到此參數
getContact(:Date)
getContact()
4.Separate Query from Modifier 將查詢函式和修改函式分離
一個函式回傳狀態又修改物件狀態
純return 值最好
把查詢與修改函式分開
例:一旦有人入侵 程式會告訴我入侵者的名字並發送一個警報
String foundMiscreant(String[] people){
for(int i=0; i < people.lenght; i++){
if(people[i].equals("Don")){
sendAlert();
return "Don";
}
if(people[i].equals("John")){
sendAlert();
return "John";
}
}
return "";
}
改函數被下列代碼調用
void checkSecurity(String[] people){
String found = foundMiscreant(people);
someLaterCode(found);
}
为了將查詢動作和修改動作分開,首先建立一個适當的查詢函數,使其與修改函數返回相同的值,但不造成任何副作用:
String foundPerson(String[] people){
for(int i=0; i < people.lenght; i++){
if(people[i].equals("Don")){
return "Don";
}
if(people[i].equals("John")){
return "John";
}
}
return "";
}
void foundMiscreant(String[] people){
for(int i=0; i < people.lenght; i++){
if(people[i].equals("Don")){
sendAlert();
return;
}
if(people[i].equals("John")){
sendAlert();
return;
}
}
}
最後修改成
void checkSecurity(String[] people){
foundMiscreant(people); //響起警報
String found = foundPerson(people); //找到哪個人
someLaterCode(found);
}
5.Parameterize Method 令函式攜帶參數
若多個函式都做了相同的事情 簡化一個
function fivePercentRaise() {
return $this->salary *= 1.05;
}
function tenPercentRaise() {
return $this->salary *= 1.1;
}
function raise($factor) {
return $this->salary *= (1 + $factor);
}
6.Replace Parameter with Explicit Methods 以明確函式取代參數
一個函式其內完全取決於參數而採取不同反應 (與5相反)
void setValue (String name, int value) {
if (name.equals("height")) {
_height = value;
return;
}
if (name.equals("width")) {
_width = value;
return;
}
Assert.shouldNeverReachHere();
}
void setHeight(int arg) {
_height = arg;
}
void setWidth (int arg) {
_width = arg;
}
7.Preserve Whole Object 保持物件完整
從某個物件中取出若干值,將它們作為某一次的韓式呼叫用
改用傳遞整個物件
int low = daysTempRange().getLow();
int high = daysTempRange().getHigh();
withinPlan = plan.withinRange(low, high);
withinPlan = plan.withinRange(daysTempRange());
8.Replace Parameter with Methods 以函式取代參數
喚起某函式,return結果作為參數,再傳給另一個函式,
則接受該參數的的函式 有能力喚起前一個函式。
int basePrice = _quantity * _itemPrice;
discountLevel = getDiscountLevel();
double finalPrice = discountedPrice (basePrice, discountLevel);
withinPlan = plan.withinRange(daysTempRange());
9.Introduce Parameter Object 引入參數物件
某些參數總是自然地出現
10.remove setting method 移除設值函式
你的class中的某個欄位,應該在物件被創建時被設值,然後不再改變
去掉該欄位所有設值函式
class Account {
private String _id;
Account (String id) {
setId(id);
}
void setId (String arg) {
_id = arg;
}
}
class Account {
private String _id;
Account (String id) {
_id = arg;
}
}
11.Hide Method 隱藏某個函式
這個函式從來沒有被其他Class用的時候請設為private
12.replace constructors with creation methods 以工廠函式 取代 建構式
class Employee {
...
function __construct($type) {
$this->type = $type;
}
...
}
class Employee {
Employee(int type) {
this.type = type;
}
//...
}
class Employee {
...
static function create($type) {
$employee = new Employee($type);
// do some heavy lifting.
return $employee;
}
...
}
class Employee {
static Employee create(int type) {
employee = new Employee(type);
// do some heavy lifting.
return employee;
}
//...
}
13.Encapsulate Downcast 封裝 向下轉型 動作
Move the downcast to within the method.
Object lastReading() {
return readings.lastElement();
}
Reading lastReading() {
return (Reading) readings.lastElement();
}
14.replace error code with exception 以異常取代錯誤碼
函式回傳特殊代碼,用來表示某種錯誤
Exception 來代表錯誤
function withdraw($amount) {
if ($amount > $this->balance)
return -1;
else {
$this->balance -= $amount;
return 0;
}
}
function withdraw($amount) {
if ($amount > $this->balance) {
throw new BalanceException('.......');
}
$this->balance -= $amount;
}
15.replace exception with test 以測試取代異常
Change the caller to make the test first.
面對一個 呼叫者可預先加以檢查的條件,你拋出了異常。
可先用判斷 就能去除error來 替換 Exception
function getValueForPeriod($periodNumber) {
try {
return $this->values[$periodNumber];
} catch (ArrayIndexOutOfBoundsException $e) {
return 0;
}
}
function getValueForPeriod($periodNumber) {
if ($periodNumber >= count($this->values)) {
return 0;
}
return $this->values[$periodNumber];
}