天天看點

代碼重構那些事兒

大家好,這是我今天演講的目錄,分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裡這兩種定義常量的方法,哪種更好?

代碼重構那些事兒

代碼重構那些事兒

為什麼我們不應該在Java 接口中使用Array:

https://eclipsesource.com/blogs/2014/04/11/3-good-reasons-to-avoid-arrays-in-java-interfaces

避免Array的原因之一:Array若使用不當,會造成性能問題

避免Array的原因之二:Array是面向過程程式設計領域的概念,使用Java面向對象的集合類,比如List,而不是Array

看個具體例子:

代碼重構那些事兒

看出差距了吧?

Arrays不是類型安全的!

下面的代碼能通過編譯,但是運作時會報ArrayStoreException的異常:

代碼重構那些事兒

而使用JDK的集合類比如List,就能在編譯器即檢測出這類錯誤。

Javascript裡有趣的逗号

function a() {

 console.log("I was called!");

 return "Jerry";

}

var b = a(), a;

然後執行下面的代碼:

console.log(b);

1

會列印出Jerry

再看這段代碼:

var d = (function c(){

 return a(),a;

})();

console.log(d);

會列印出:

I was called!

5

再看這段代碼呢?

(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: 7

console.log(s) // 列印出 8

function test(i){

 var result = i++;

 return

 result

console.log("test: " + test(3)) // 列印出undefined

1繼續看這段代碼

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();

// 第三種解決方案采用了面向切片程式設計思想,顯得更加進階

 // big logic

 console.log("big logic");

bigFunction = ( bigFunction || function() {} ).after( function() {

    console.log("our own logic");

});

如何優雅的在一個函數裡增添性能測試統計的工具代碼

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 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));

          });

    })();

};

log_time(append_doms, "consumed time: ")();

更優雅的解決方案:

把這些不同的檢查規則封裝到一個個JavaScript函數裡,再把這些函數作為一個規則對象的屬性:

var valid_rules = {

     not_empty: function( value ) {

        return value.length !== '';

     },

     max_length: function( value ) {

        return value.length <= MAX_LENGTH  ;

     }

}

2

3

4

6

7

8

實作一個新的檢查函數,變量檢查對象的屬性,執行校驗邏輯:

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(){

function isFlashSupported(){

好多的IF -ELSE啊:

var uploadAPI;

if ( isActiveXSupported()) {

 // lots of initialization work

 uploadAPI = { "name": "ActiveX"};

else if( isHTML5Supported()) {

 uploadAPI = { "name": "HTML5"};

else if( isFlashSupported()) {

 uploadAPI = { "name": "Flash"};

else {

 uploadAPI = { "name": "Form"};

console.log(uploadAPI);

再看職責鍊設計模式的實作:

Chain of Responsibility

var getActiveX = function() {

 try {

 return { "name": "ActiveX"};

 catch (e) {

 return null;

var getHTML5 = function() {

 return { "name": "HTML5"};

代碼整潔優雅:

代碼重構那些事兒

Java中的String

代碼重構那些事兒

用javap将上面的Hello World程式反編譯出來學習: