2014-07-02 196 views
0

今天我偶然發現了一個我在項目中看到的代碼,並且很擔心地看着它。我不知道爲什麼他們將這些作爲靜態方法,因爲它們改變了對象的狀態。下面靜態方法改變狀態對象

是代碼

@Controller 
CruiseController{ 

getCruiseSearchResults(){ 
//prepare cruise serach request, static method in CruiseHelper 
CruiseSearchRequest cruiseReq = CruiseHelper.prepareRequest(); 
...futher impl  

} 

/** my helper class which has utlity methods */ 
CruiseHelper{ 
    public static CruiseSearchRequest prepareRequest(){ 
     CruiseSearchRequest cruiseRequest = new CruiseSearchRequest(); 

    // all below methods are static 
    setCruiseTypeandDestination(cruiseRequest) 
    setStartAndEndDate(cruiseRequest) 
    setShipAndDeparturePort(cruiseRequest) 
    setDurationAndAccesiblity(cruiseRequest) 
    setPromoType(cruiseRequest) 
    setResultPreferences(cruiseRequest) 

    return cruiseSearchCriteriaDTO 
} 

static void setCruiseTypeandDestination(CruiseSearchRequest cruiseRequest){ 

    /** changing the state of object in static method */ 
    cruiseRequest.setCruiseType("ABC"); 
    cruiseRequest.setCruiseType("Alaska"); 
} 

//.... further static methods as above, all of them 
//change the state of cruiseRequest 
} 

,所以我知道的是,上述方法不應是靜態的,因爲他們都有每個請求的性質。但是代碼正在工作,並且在執行任何負載測試時未失敗。

我的一個重要問題是:「上面的代碼可以考慮嗎?」和「如果是的話,這可能會失敗,那麼在什麼情況下?」

回答

2

確實,這些方法改變了一個對象的狀態,但它是一個作爲參數給予它的對象,這是非常有效且合理的。

static意味着該方法綁定到對象定義(類)而不是任何特定的對象實例。因此靜態方法不能更改它自己的對象的狀態,因爲它沒有一個實例可以使用(它沒有this)。

我建議你讀一下靜態和類變量:Understanding Class Members

1

靜態方法用於暗示該方法不需要調用類的實例。例如,考慮一下String類。它仍然可以改變任何物體的狀態。

replaceAll()不是一個靜態方法,因爲它需要一個實例來處理。因爲valueOf()不是因爲它不需要一個String實例。

我建議你重溫Java的基礎知識。

0

Spring中的方法不應該是靜態的,不是因爲它們不能工作,而是因爲它在應用程序體系結構方面是一個糟糕的決定。靜態方法在單元測試方面是錯誤的決定 - 嘲笑靜態方法比對象更難。另外我認爲,對靜態方法的大量使用打破了依賴注入的概念,並且代碼變得更加緊密耦合。 Here是關於此主題的不錯文章。

1

我沒有意識到爲什麼他們將這些作爲靜態方法,因爲他們改變對象的狀態。

因爲他們是類CruiseController類的方法。他們正在修改CruiseSearchRequest這個不同類別的實例。你不能這樣做cruiseSearchRequest.setCruiseTypeandDestination();,因爲方法setCruiseTypeandDestination不在CruiseSearchRequest類。因此,它接收CruiseSearchRequest對象作爲參數,並且由於它不受限於CruiseController的任何實例,因此它是該類的靜態方法。

如果您將移動到CruiseSearchRequest類,您可以使這些方法非靜態。但是,你不需要。在靜態方法中修改對象絕對沒有什麼技術上的錯誤。它可能或可能不是您的特定程序的好設計,但它不會「失敗」。