星期一, 6月 07, 2004

強迫性 Immutable 症候群

自從看了 Domain-Driven Design 這本書之後,唉~ 不知該說好還是壞。就說裡面提到的 Side-effect free function 吧。side-effect free指的是 object 是 immutable 的,做了改變不會影響到本身也不會氾濫到其他的 object,而 function 則是指這個 method 可以執行多次而結果都一樣 (數學的 function 都是這樣)
直覺式的錢包計算:

//[code snip #1]
public class MoneyBag {
  private int asset ;
  public void spend(int expenditure) {
    asset -= expenditure;
  }
}

這樣夠嗎?當然不夠,還要加 precodition 和 post-condition:

//[code snip #2]
public class MoneyBag {
  private int asset ;
  public void spend(int expenditure) {
    if(expenditure <= 0)
      throw new IllegalArgumentException();
    final int diff = asset - expenditure;
    if(diff < 0){
      throw new InsuffienctMoneyException();
    }
    asset = diff;
  }
}

夠醜吧,真正的 logic 只有一行,卻弄成啊哩啊扎的
如果另外寫個 Immutable Value Object "Money":

//[code snip #3]
public class Money {
  private int dollar ;
  public Money(int dollar) {
    if(dollar <= 0)
     throw new IllegalArgumentException();
    this.dollar = dollar ;
  }
  public Money minus(Money money) {
    int diff = this.dollar - money.dollar ;
    if(diff < 0){
     throw new InsuffienctMoneyException();
    }
    return new Money(diff) ;
  }
}

MoneyBag 就不用再煩惱 "錢" 的問題了,變得很簡捷:

//[code snip #4]
public class MoneyBag {
  private Money asset;
  public void spend(Money expenditure) {
    asset = asset.minus(expenditure);
  }
}

spend() 變得超直覺的 ==> "剩下的錢等於現在的錢 minus 消費額"
再看另一個例子:

//[code snip #5]
public Money calculateDiscount(Money expenditure) {
  Money allowance = expenditure.multply(0.9) ;
  return expenditure.minus(allowance);
}

不會有人看不懂這個method在做什麼吧.... 已經非常非常白話了。
  • minus() 這個 method 重用了
     
  • 隨便你怎麼 call、怎麼組合、call多少次都不會錯
     
  • 核心邏輯可讀性很好,接手維護的人會感動到哭

這些優點都是歸功於 Side-effect free function 的設計理念。真是棒呆了...... 呃... 事情若這麼順利就好了。自從看完這個章節後.... 我的眼中只容的下 Immutable Object ! 哇咧~~ 一看到有什麼 method 不是 immutable 的,就想做 refactoring。再加上功力又不太夠,沒辦法很正確的判斷,搞得 原來的 class 一團亂 -_-;;。而且,本來嘛,那個 MoneyBag 是一個 class 就搞定了,現在要多生一個 Money class 出來,Immutable 好像天生就很容易增加 class 數量的樣子... 這樣到後來也不怎麼好維護吧?!

唉~ 不知該說好還是壞~~

0 Comments:

張貼留言

<< Home