簡體   English   中英

為什么'Manager'類中的'getter'方法不是靜態的?

[英]Why should 'getter' methods in 'Manager' classes not be static?

在大多數情況下,傳統的編程智慧似乎不鼓勵使用靜態方法。 通常,我有這些“經理”,例如UserManager,AppointmentManager等。經理中的方法之一總是XXX getXXX(long xxxId)例如User getUser(long userId) 我真的不明白為什么這不能成為靜態方法。 看起來非常像工廠方法(GoF工廠模式)。 很難忽略以下便利:

User user = UserManager.getUser(id);

和使用

UserManager userManager = new UserManager(); User user = userManager.getUser(userId);

代替。

PS,我相信測試; 我不是“模擬測試”迷,所以除了嘲笑外,我還需要其他理由。

在對象工廠中避免使用靜態方法的主要原因是保持狀態的能力。 盡管靜態方法可以將其狀態保留在靜態字段中,但是這種方法使保存和重置工廠狀態變得困難。

另外,由於無法將靜態方法用作接口實現,因此無法編程為工廠接口。 當您需要將對象的實現透明地切換到應用程序的其余部分時,這一點就變得很重要。

最后,無論有無模擬,靜態方法都使測試代碼變得更加困難。 測試很難驗證工廠的某些方法是按特定順序調用的。

我認為Bob叔叔在他的Clean Code書中對此做了出色的解釋(敬請閱讀btw)。 但是無論如何,他的觀點是,您不應該在想要利用多態性的任何地方使用靜態方法(我認為正是上述情況所需要的)。

就您而言,您有一個UserManager。 絕對不是完整的申請,對不對? 您可能需要使用UserManager進行更復雜的操作。 假設您有自己的StackOverflow版本(當然不要這樣做,stackoverflow非常棒,不需要競爭)。

好的,所以我們有一個LoginUser,它調用UserManager.getUser()。 這是一個不可改變的依賴關系(因為我們沒有利用多態性)。 如果UserManager.getUser()需要基礎SQL數據庫,請猜測您需要運行(或測試)LoginService ... SQL數據庫!

public class LoginService {
   public boolean authenticate(String username, String password) {
      User user = UserManager.getUser(username); // hard dependency on implementation
      // other stuff
   }
} 

更為普遍的解決方案是抽象出可以在接口后面更改的內容。 這樣,您可以換出實現。 LoginService的工作應該經過測試,實際上不應該依賴於特定的數據庫實現。

public interface UserManager {
   User getUser(String id):
}

public class SQLUserManager implements UserManager {
   @Override
   public User getUser(String id) { // SQL stuff }
}

class LoginService {
   public LoginService(UserManager userManager) {
      this.userManager = userManager;
   }

   public boolean authenticate(String username, String password) {
      User user = userManager.getUser(username);
      // other stuff
   }
} 

現在,LoginService可以1)與使用UserManager無關地進行測試,並且2)如果用戶實現發生更改,可以單獨使用。

這不是模擬,而是測試組件而無需設置整個應用程序堆棧。

通常不建議靜態保持狀態,而建議使用依賴項注入。 如dasblinkenlight所述,靜態方法無法實現interfaces。 使用靜態狀態使得不可能有該類的多個實例。
如果您需要兩個不同的用戶管理器來指向不同的數據源,則必須進行主要的重構。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM