程式碼重構那些事兒
大家好,這是我今天演講的目錄,分Java,JavaScript,ABAP三門程式語言來講述。
Java
•JAD
•javap
•Java Decompiler
•Source Monitor
•Visual VM
•Refactor Menu in Eclipse
ABAP
•Code inspector
•Refactor feature in AIE
•Code coverage
JavaScript
•ESLint for Fiori Apps
•Check Jenkins build log
•JSlint for Sublime Text 2
•Code check in WebIDE
•Profile in Chrome
在方法裡引入一個布林型別的引數控制方法的行為,這種做法正確嗎?
看看stackoverflow上是怎麼說的。
Java裡定義常量的最佳實踐:
http://developer.51cto.com/art/201509/492085.htm
Java裡這兩種定義常量的方法,哪種更好?
package one;public interface Constants { String NAME = "孫悟空"; int BP = 10000; }
或
package two;public class Constants { public static final String NAME = "貝吉塔"; public static final int BP = 9000; }
為什麼我們不應該在Java 介面中使用Array:
https://eclipsesource.com/blogs/2014/04/11/3-good-reasons-to-avoid-arrays-in-java-interfaces
避免Array的原因之一:Array若使用不當,會造成效能問題
避免Array的原因之一:Array若使用不當,會造成效能問題
避免Array的原因之二:Array是程式導向程式設計領域的概念,使用Java物件導向的集合類,比如List,而不是Array
看個具體例子:
String[] array = { "賈伯斯", "張小龍" }; List list = Arrays.asList( array ); System.out.println( list );// 列印輸出 [賈伯斯, 張小龍]System.out.println( array );// -> [Ljava.lang.String;@6f548414list.equals( Arrays.asList( "賈伯斯", "張小龍" ) )// -> truearray.equals( new String[] { "賈伯斯", "張小龍" } )// -> false
看出差距了吧?
Arrays不是型別安全的!
下面的程式碼能通過編譯,但是執行時會報ArrayStoreException的異常:
Number[] numbers = new Integer[10]; numbers[0] = Long.valueOf( 0 );
而使用JDK的集合類比如List,就能在編譯器即檢測出這類錯誤。
Javascript裡有趣的逗號
function a() { console.log("I was called!"); return "Jerry"; }var b = a(), a;
然後執行下面的程式碼:
console.log(b);
會列印出Jerry
再看這段程式碼:
var d = (function c(){ return a(),a; })();console.log(d);
會列印出:
I was called!function a() { console.log("I was called!"); return "Jerry"; }
再看這段程式碼呢?
(function() { var e = f = 1; })();
直接報錯:Uncaught ReferenceError: f is not defined
JavaScript裡有趣的分號
var b = function(para) { return { doSomething: function() { console.log("hello: " + para); return para; } } }var a = 1, x = 3, y = 4, s s = a + b (x + y).doSomething() // 列印出 hello: 7console.log(s) // 列印出 8function test(i){ var result = i++; return result }console.log("test: " + test(3)) // 列印出undefined
繼續看這段程式碼
s = function(x){ console.log("called: " + x ); return x} (1 + 2).toString() s = function(x){ console.log("called: " + x ); return x}(1 + 2).toString()// 列印出 called: 3
小技巧 - 如何把您自己增強邏輯植入到legacy遺留程式碼中
var bigFunction = function() { // big logic console.log("big logic"); // 這句話模擬我們在一段很冗長的遺留程式碼裡植入自己的新邏輯}// 下面這種解決方案不會直接修改遺留函式本身,顯得比較優雅var _old = bigFunction; bigFunction = function() { if ( _old ) { _old(); } console.log("our own enhancement"); } bigFunction();// 第三種解決方案採用了面向切片程式設計思想,顯得更加高階var bigFunction = function() { // big logic console.log("big logic"); } bigFunction = ( bigFunction || function() {} ).after( function() { console.log("our own logic"); }); bigFunction();
如何優雅的在一個函式裡增添效能測試統計的工具程式碼
var append_doms = function() { var d = new Date(); // dirty code - nothing to do with application logic!!! for( var i = 0; i < 100000; i++) { var div = document.createElement( "div"); document.body.appendChild(div); } // dirty code - nothing to do with application logic!!! console.log(" time consumed: " + ( new Date() - d)); };function test() { append_doms(); }
傳統方案:在充滿了業務邏輯的函式體裡強行加入紅色標準的蒐集效能測試的工具程式碼,這個實現顯得很醜陋:
再看看採用面向切片程式設計思路的解決方案:AOP - Aspect Oriented Programming
var append_doms = function() { for( var i = 0; i < 100000; i++) { var div = document.createElement( "div"); document.body.appendChild(div); } };var log_time = function( func, log_name) { return func = ( function() { var d; return func.before( function(){ d = new Date(); }).after( function(){ console.log( log_name + ( new Date() - d)); }); })(); };function test() { log_time(append_doms, "consumed time: ")(); }
如何避免程式碼中大量的IF - ELSE 檢查
在呼叫真正的OData API之前,系統有大量的IF ELSE對API的輸入參宿進行檢查:
var send = function() { var value = input.value; if( value.length === '' ) { return false; } else if( value.length > MAX_LENGTH) { return false; } ... // lots of else else { // call OData API } }
更優雅的解決方案:
把這些不同的檢查規則封裝到一個個JavaScript函式裡,再把這些函式作為一個規則物件的屬性:
var valid_rules = { not_empty: function( value ) { return value.length !== ''; }, max_length: function( value ) { return value.length <= MAX_LENGTH ; } }
實現一個新的檢查函式,變數檢查物件的屬性,執行校驗邏輯:
var valid_check = function() { for( var i in valid_rules ) { if ( vali_rules[i].apply( this, arguments) === false ) { return false; } } }
現在的OData呼叫函式非常優雅了:
var send = function( value ) { if ( valid_check( value ) === false ) { return; } // call OData API}
通過這種方式消除了IF ELSE。
另一種通過職責鏈 Chain of Responsibility 的設計模式 design pattern消除IF ELSE分支的程式碼重構方式:
先看傳統方式的實現:
// Priority: ActiveX > HTML5 > Flash > Form(default)function isActiveXSupported(){ //... return false; }function isHTML5Supported(){ //... return false; }function isFlashSupported(){ //... return false; }
好多的IF -ELSE啊:
var uploadAPI;if ( isActiveXSupported()) { // lots of initialization work uploadAPI = { "name": "ActiveX"}; }else if( isHTML5Supported()) { // lots of initialization work uploadAPI = { "name": "HTML5"}; }else if( isFlashSupported()) { // lots of initialization work uploadAPI = { "name": "Flash"}; }else { // lots of initialization work uploadAPI = { "name": "Form"}; }console.log(uploadAPI);
再看職責鏈設計模式的實現:
Chain of Responsibility
var getActiveX = function() { try { // lots of initialization work return { "name": "ActiveX"}; } catch (e) { return null; } }var getHTML5 = function() { try { // lots of initialization work return { "name": "HTML5"}; } catch (e) { return null; } }
程式碼整潔優雅:
var uploadAPI = getActiveX.after(getHTML5).after(getFlash).after(getForm)();console.log(uploadAPI);
Java中的String
public class stringTest { public static void main(String[] args) { String userName = "Jerry"; String skill = "JS"; String job = "Developer"; String info = userName + skill + job; System.out.println(info); } }
用javap將上面的Hello World程式反編譯出來學習:
要獲取更多Jerry的原創文章,請關注公眾號"汪子熙":
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24475491/viewspace-2565434/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 字元編碼那些事兒字元
- 讓人疑惑的Java程式碼 – Java那些事兒Java
- [apue] 等待子程式的那些事兒
- PHP那些事兒PHP
- Redis那些事兒Redis
- babel那些事兒Babel
- 架構那些需要注意的事兒架構
- Java程式碼的編譯與反編譯那些事兒Java編譯
- 程式設計師兼職那些事兒程式設計師
- https的那些事兒HTTP
- webpack的那些事兒Web
- 圈複雜度那些事兒-前端程式碼質量系列文章(二)複雜度前端
- 關於程式碼評審(CodeReview)那些不得不說的事兒View
- MySQL優化那些事兒MySql優化
- 網路安全那些事兒
- Eval家族的那些事兒
- 說說RCE那些事兒
- C語言那些事兒C語言
- PHP 閉包那些事兒PHP
- XSS與字元編碼的那些事兒 ---科普文字元
- 密碼安全和無密碼身份認證那些事兒密碼
- J2EE遠端程式碼執行那些事兒(框架層面)框架
- 小白入門學習Python,值得你重視的那些事兒Python
- 雲原生java的那些事兒Java
- util.promisify 的那些事兒
- 「前端那些事兒」④ 效能監控前端
- iOS 截圖的那些事兒iOS
- HTTP 快取的那些事兒HTTP快取
- 法線貼圖那些事兒
- 漏洞檢測的那些事兒
- 關於 sudo 的那些事兒
- Node檔案操作那些事兒
- 面試的那些事兒--01面試
- leobert重構程式碼二三事--一.可怕的低階程式碼
- 分散式系統的那些事兒 - SOA架構體系分散式架構
- 前端註釋那些事兒:看懂這篇,提高程式碼質量So easy前端
- 「前端那些事兒」③ CSS 佈局方案前端CSS
- webpack4.0優化那些事兒Web優化