重構之臨時變數(Replace Temp with Query)
當你的程式以一個臨時變數儲存某一表示式的運算結果
將這個表示式提煉到一個獨立函式中,將這個臨時變數的所有[被引用點]替換為[對新函式的呼叫],新函式可被其他函式使用
java 程式碼
- double basePrice=_quantity * _itemPrice;
- if(basePrice>1000){
- return basePrice * 0.95;
- else
- return basePrice * 0.38;
- }
- ......
提煉後:
java 程式碼
- if (basePrice()>1000){
return basePrice() * 0.95 - else
- return basePrice() * 0.38
- }
- ......
- double basePrice(){
- return _quantity * _itemPrice;
}
動機:
臨時變數的問題在於:它們是暫時的,而且只能在所屬函式內使用,由於臨時變數只有在所屬內才可見,所以它們會驅使你寫出更長的函式,因為只有這樣你才能訪問到想要訪問的臨時變數,如果把臨時變數替換為一個查詢式(query method),那麼同一個CLASS中的所有函式都將獲得這份資訊。這將帶給你極大幫助,使你能夠為這個CLASS編寫更清晰的程式碼。
這個重構手法較為直率的情況就是:臨時變數只被賦值一次,或者賦值給臨時變數的表示式不受其他條件影響,其他情況比較情況棘手,但也有可能發生,你可能需要先運用Split Temporary Variable 或Separate Query from Modifier 使情況變得簡單一些。如果你想替換的臨時變數是用來收集結果的(例如迴圈中的累加值),你就需要將某些程式的邏輯(例如迴圈)拷貝到查詢式(query method)去。
作法:
- 找出只被賦值一次的臨時變數
- 將臨時變數宣告為 final
- 編譯(這可確保臨時變數的確只被賦值一次)
- 將對該臨時變數賦值之語句的等號右側部分提煉到一個獨立函式中。詳細步驟:首先將函式宣告為private,之後你可能會發現有更多CLASS需要使用它,彼時你可輕易放鬆對它的保護。確保提煉出來的函式無任何連帶影響,就對它進行Separate Query from Modifier
- 編譯,測試
範例:
首先,我從一個簡單函式開始:
java 程式碼
- double getPrice()
- {
- int basePrice=_quantity+_itemPrice;
- double discountFactor;
- if(basePrice>1000)
- discountFactor=0.95;
- else
- discountFactor=0.98;
- return basePrice = discountFactor;
- }
我希望將這個兩個變數都替換掉,當然,每次一個。
儘管這裡的程式碼十分清楚,我還是先把臨時變數宣告為final,檢查它們是否的確只被賦值一次:
java 程式碼
- double getPrice()
- {
- final int basePrice = _quantity * _itemPrice;
- final double discountFactor;
- if(basePrice>1000)
- discountFactor=0.95;
- else
- discountFactory=0.98;
- return basePrice * discountFactor;
- }
這麼一來,如果有任何問題,編譯器就會警告我,之所以先做這件事,因為如果臨時變數不只被賦值一次,不該進行這項重構了,接下來我開始替換臨時變數了,每次一個,首先我把賦值動作的右側表示式提煉出來。
java 程式碼
- double getPrice()
- {
- final int basePrice = basePrice();
- final double discountFactor;
- if(basePrice >1000)
- discountFactor =0.95;
- else
- discountFactor =0.98;
- return basePrice * discountFactor;
- }
- private int basePrice()
- {
- return _quantity * _itemPrice;
- }
再把臨時變數的引用點替換掉:
java 程式碼
- double getPrice()
- {
- final int basePrice = basePrice();
- final double discountFactor;
- if ( basePrice()>1000 )
- discountFactor = 0.95;
- else
- discountFactor = 0.98;
- return basePrice() * discountFactor;
- }
下一步:
java 程式碼
- double getPrice()
- {
- final double discountFactor;
- if ( basePrice()>1000 )
- discountFactor = 0.95;
- else
- discountFactor = 0.98;
- return basePrice() * discountFactor;
- }
下一步(仔細觀察程式碼)
java 程式碼
- double getPrice()
- {
- return basePrice() * discountFactor();
- }
- private double discountFactor()
- {
- if ( basePrice()>1000 )
- return 0.95;
- else
- return 0.98;
- }
- private int basePrice()
- {
- return _quantity * _itemPrice;
- }
是多麼簡單啊(程式碼有錯請指點)
相關文章
- PLC結構化文字(ST)——臨時&靜態&例項-變數(TEMP&STAT&INST)變數
- Oracle Temp 臨時表空間Oracle
- Oracle TEMP臨時表空間概念Oracle
- SQLServer表變數和臨時表系列之概念篇SQLServer變數
- Oracle Temp臨時表空間處理Oracle
- Oracle 12c 新特性之臨時Undo--temp_undo_enabledOracle
- 程式碼重構與單元測試——使用“以查詢取代臨時變數”再次對Statement()方法進行重構(七)變數
- SQLServer臨時表和表變數系列之踢館篇SQLServer變數
- Oracle基礎 02 臨時表空間 tempOracle
- 不使用臨時變數交換兩個變數的值變數
- JavaScript兩個變數交換值(不使用臨時變數)JavaScript變數
- 迴圈內臨時變數問題變數
- 再議臨時表和表變數變數
- c++臨時變數的作用域C++變數
- 怎麼清理temp資料夾的臨時檔案?Win7系統電腦temp臨時檔案的清理方法Win7
- 變數的分類(臨時(本地)變數、環境變數、全域性變數和系統變數)變數
- 如何不使用臨時變數,交換兩個變數的值。變數
- C++臨時變數的生命週期C++變數
- Oracle 12c 新特性 - 臨時表undo(TEMP UNDO)Oracle
- 改變無法改變的Query 變數變數
- debian修改臨時環境變數支援中文變數
- SQL Server中的臨時表和表變數SQLServer變數
- 【TEMP】臨時表空間的工作原理及維護方法
- c語言 - 交換兩個變數(不建立臨時變數)兩種方法C語言變數
- 表變數和臨時表的差別 (以前把表變數叫成變數表了,哎。。。)變數
- [20181108]with temp as 建立臨時表嗎.txt
- 非const引用不能指向臨時變數變數
- python設定環境變數(臨時和永久)Python變數
- 變數含義,臨近變化變數
- Sqlserver 關於臨時表和表變數的總結SQLServer變數
- SQL Server中臨時表與表變數的區別SQLServer變數
- MySQL之臨時表MySql
- Linux中修改環境變數及生效方法(永久、臨時)環境變數檢視Linux變數
- 12C關於CDB、PDB 臨時temp表空間的總結
- Oracle 11g中Temp臨時表空間、檔案的新特性Oracle
- TempDB 中表變數和區域性臨時表的對比變數
- 翻譯|Rust臨時變數的生命週期和“Super Let”Rust變數
- 【重構】微信小程式倒數計時元件微信小程式元件