關于返回 Null 值的問題

fmms 12年前發布 | 6K 次閱讀 編程

本文是從 Returning Null 這篇文章翻譯而來。


我總感覺一個方法返回null值有問題。當讀了Misko Hevery關于how to think about OO的博客文章后,又讓我想起這個問題。

我感覺返回null值是有問題的,它大量的被使用在一個方法有不同的返回類型時。簡單的用谷歌搜索一下“returning null”,你就會發現有建議把返回類型做成一個null對象。返回一個Null對象在某些情況下是合適的,但并不適合當你需要向客戶端傳送兩種不同的東 西的情形。用Misko重構的一段代碼來說明這個問題。他重構的是一段登錄代碼(我非常喜歡他的過程),這段代碼大概是這個樣子:

  Cookie login(Ldap ldap) {
    if ( ldap.auth(user, password) )
      return new Cookie(user);
    return null;
  }

從這段代碼,可以看出兩種情況(從結構上講)

  1. 如果認證通過,客戶端會被通知驗證成功,生成一個新的Cookie
  2. 如果認證失敗,則通過返回的null值通知客戶端

客戶端的方法應該是什么樣的?

  public void authenticateUser(User user) {
     Cookie userCookie = user.login(ldap);
     if (userCookie == null) {
           //notify someone that auth failed
     } eles {
           //register them as logged in
     }
  }

我們在兩個地方做了相同的事情,只是在語法上有稍微的不同,每個地方,我們都要檢查驗證是否成功。如果我們使用IoC(反向控制)模式,或“Tell Don’t Ask”模式或“Hollywood原則”,會如何?

  Cookie login(Ldap ldap, AuthenticationRegistry authenticationRegistry) {
    if ( ldap.auth(user, password) )
      authenticationRegistry.authSucceeded(new Cookie(user));
    authenticationRegistry.authFailed(user);
  }

客戶端:

  public void authenticateUser(User user) {
     user.login(ldap,this);
  }

  public void authSucceeded(Cookie cookie) {
     //register them as logged in
  }

  public void authFailed(User user) {
     //register them as auth failed
  }

新代碼稍微有點復雜,但我感覺它很清晰,實現的更直接。現在我們的兩個實體能夠相互通信,我們定義了它們通信的方式。我喜歡Misko的重構,我只是更進了一步。好壞可以再討論,但我想,如果你遇到了這種需要返回兩種情況的方法時,IoC是你應該的選擇。

本文轉載自: 外刊IT評論 http://www.aqee.net/

 本文由用戶 fmms 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!