2010年5月28日金曜日

柔軟なエンティティの拡張

uehajさんの最近の一連の "DCIらぶ" な投稿を読んでいて, 大昔, Grailsでこんなプラグインを書いて遊んでいたのを思い出しました.

一つは動的に役割を与えるものです.

例えば

class Person { String name; String type }

というクラスがあったとします.

def john = new Person(name:"john", type:"contracted")

とすると, john は契約社員なので契約期間など契約社員特有のプロパティにアクセスできます.

john.fromDate = new Date("2010/6/1")

一方

def paul = new Person(name:"paul", type:"official")

とすると, paulは正社員なので給料など正社員特有のプロパティにアクセスできます.

paul.salary = 1200

これは実はmissingPropertyを利用して, typeの値に応じてそれぞれクラスContractedPerson, OfficialPersonのプロパティにアクセスできるようにしているだけなんですね.

typeの値によって, 動的にインスタンスごとに異なる役割を持たせることができるわけです.

もう一つはドメインクラスの定義を変えずに, ビュー (プロパティ・セット) を追加していくものです.

class Person { String name; static allowView = true }

としておくと

def george = new Person(name:"george")
george['contact'].tel = "0123-456-789"

これも前の例と同じようにmissingPropertyを利用して, クラスPersonContactにアクセスするようにしているだけです.

ビューであることを明示するために george['contact'] とかしていますが, もちろん普通にgeorge.contactと書いても同じです.

grailsのドメイン・クラスに対して, 単純にmixinしたり, categoryを追加しても駄目なんで, こんなことしていたわけですね...