代碼重構那些事兒

你們好,這是我今天演講的目錄,分Java,JavaScript,ABAP三門編程語言來說述。javascript

Java

•JAD
•javap
•Java Decompiler
•Source Monitor
•Visual VM
•Refactor Menu in Eclipsejava

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裏定義常量的最佳實踐:app

http://developer.51cto.com/ar...dom

Java裏這兩種定義常量的方法,哪一種更好?eclipse

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/blo...

避免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;@6f548414

list.equals( Arrays.asList( "喬布斯", "張小龍" ) )
// -> true
array.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: 7
console.log(s) // 打印出 8
function 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的原創文章,請關注公衆號"汪子熙":

相關文章
相關標籤/搜索