2016-08-05 72 views
1

最近我已經重組了一個Java代碼,試圖儘可能地消除static東西(變量和方法),並用更好的編碼實踐取而代之。反射VS靜態東西

我也開始學習思考,發現它可以讓我做一些事情說,起初,我只能實現(或者,至少,這就是我看到它)與static電話或引用。

然而,雖然我一直在閱讀,但不推薦使用static,它似乎與反思不一樣。

所以,我問:不是的製作方法static,並要求它像ClassName.methodName(),它是一個合法的使用反射使它成爲一個實例方法,並通過調用java.lang.reflect.Method.invoke()它?


像動態訪問類的內容


下面是一個代碼示例:

假設性的情況,工程(但我不想使該方法static) :

import static java.lang.System.out; 


public class Foo 
{ 
    private static boolean light; 


    public Foo() 
    { 
     turnOn(); 
    } 

    public static void turnOn() 
    { 
     light = true; 
    } 

    public static void turnOff() 
    { 
     light = false; 
    } 

    public static boolean isGreenLight() 
    { 
     return light; 
    } 
} 

public class Boo 
{ 
    public Boo() 
    { 
     if (Foo.isGreenLight())  // I need to access Foo.isGreenLight() from here, but cur- 
     {        // rently that method is not static (it should be to do so) 
      out.println("Ok!"); 
     } 
    } 
} 

public final class Main 
{ 
    public static void main(String[] args) 
    { 
     final Boo boo = new Boo(); 
    } 
} 

假設情況針對這樣也應努力(如何會被使用反射):

import static java.lang.System.out; 
import java.lang.reflect.Method; 


public class Foo 
{ 
    private boolean light; 


    public Foo() 
    { 
     turnOn(); 
    } 

    public void turnOn() 
    { 
     this.light = true; 
    } 

    public void turnOff() 
    { 
     this.light = false; 
    } 

    public boolean isGreenLight() 
    { 
     return this.light; 
    } 
} 

public class Boo 
{ 
    public Boo() 
    { 
     if ((boolean) Class.forName("Foo").getMethod("isGreenLight", null).invoke(new Foo(), null)) 
     { 
      out.println("Ok!"); 
     } 
    } 
} 

public final class Main 
{ 
    public static void main(String[] args) 
    { 
     final Boo boo = new Boo(); 
    } 
} 

預期輸出(未經測試):

好!

+1

這不是一個如何進行調用(直接與反射),而是關於將方法*本身*改爲非靜態的問題。如果您只是將直接調用更改爲反射調用,但將該方法保留爲靜態方法,那麼您只是讓代碼*變得更糟!! * – Andreas

+1

您究竟意味着什麼「從該方法中檢索值」 ?獲取它返回的價值?也許你應該給一些代碼示例。 –

+0

@Andreas是的,我正在談論將方法更改爲非靜態方法,並通過Reflection訪問它 –

回答

4

使用反射是一種代碼異味,特別是如果您正在編寫的背後的意圖不能保證它。

沒有看到代碼很難說更多,因爲它只是猜測。

我想:

  • 枚舉後面爲什麼要擺在首位

  • 確定static修改,其實是擺在首位的正確決定有那些static成員的原因:即這些應該是實例還是類成員?這些課程的「客戶」如何使用它們?我使用什麼樣的範例?功能或面向對象的代碼。它是否滿足DRY,SOLID和KISS編程實踐?

  • 考慮,如果我過工程放在首位

更重要的是:

  • 我將通過測試第一,驅動的設計,設計我的代碼你通過用戶的眼睛獲取API,以及在實施前已經測試過的額外好處。通常,當以這種方式編寫代碼時,我排除了這樣的問題,因爲從用戶的角度而不是設計者的角度來看,解決方案更爲明顯。它成爲一種實用主義問題,而不是滿足建築設計目標和理念。
+0

我不確定你是否正在設計第一點。我覺得'靜態'被過度使用的OP,但我承認這是很難說沒有例子 –

+0

如何證明設計決策是過度工程? –

+0

對不起,如果我的評論是模棱兩可的。我的意思是我幾乎可以肯定,這不是過度工程。我只是提到你的第三點。我完全同意你的答案的確如此。 –