勉強日記

チラ裏

PoEAA ch18 Special Case

martinfowler.com


Special Case

A subclass that provides special behavior for particular cases.

  • null撲滅委員会
    • 静的型付き言語では、コンパイラチェックがある
    • が、nullはこれをすり抜けて実行時エラーを引き起こす
  • nullが来そうなところはnullチェックで囲む?
    • コード重複しまくりになる
  • この種の問題を引き起こすのはnullだけではない
    • 浮動小数点数型の特殊な値
      • infinity
      • NaN
    • 誰だかわからない顧客を表す"occupant"
  • nullや変な値を返す代わりにSpecial Case使え

How It Works

  • 特殊なケースを表すサブクラスを生やす
    • class NullCustomer extends Customerって感じ
  • 本家の振る舞いを無害な振る舞いでオーバライドする
    • 【補】何もしないsetter
    • Special Caseを返すgetter
      • getLastBill()new UnknownBill()を返すとか
  • Customer customernullを代入していた局面で代わりに NullCustomerインスタンスを代入するようにする
  • 複数のNull Customerインスタンスを区別する必要が無い場合は、GoFFlyweight Patternを適用できる
    • 「誰だかわからないがとにかく顧客が存在する」Occupant Customerのような場合は、インスタンスの区別が必要なので適用不可
    • 【補】p.498のコード例では、Contract.NULLというstatic定数フィールドにNullContractインスタンスを持っている
  • nullの意味するところ
    • 存在しない
      • 【補】Not Applicable (N/A)
    • 存在するが、わからない
      • 【補】Unknown
    • これらを混同しないためにもSpecial Caseの適用を検討せよ

When to Use It

  • 同じ「条件分岐->振る舞い」が散らばっているとき
    • 条件分岐にはnullチェックも含まれる

Further Reading

  • 本書執筆時点でSpecial Caseをパターンとして挙げている書籍はない
  • [Woolf]のNull ObjectSpecial Caseのspecial caseであるといえる

Example: A Simple Null Object (C#)

class Employee...

class NullEmployee : Employee, INull...
  • nullではないが本質的にnullであること(nullness)を明示的にチェックしたい場合、下記いずれかを行えば良い
    • isNull()メソッドを生やす
      • 【補】基底にisNull() { return true; }を生やし、
    • INullインタフェースを実装させ、型チェックを行う
      • customer instanceOf INull的なやつ