2013年9月30日月曜日

akkaのActorを抽象化する方法を試行錯誤する

akkaを使ってActorをゴリゴリ作ってると、当然Actorを抽象化したいという要求が出てくるよね。

例えばこんな方針で抽象化を試みる。

  • Actorを継承したtraitを作って、共通処理を抽象化する。
  • 作ったtraitは型パラメータを持たせて、具象クラス化するときに例えば受け取るメッセージの型を指定する。



なんでわざわざ型パラメータなんて持たせてるかというと、これをやりたい。



要するに、送受信するメッセージは処理を内包しないただの型(case class MyMessage)にしといて、その型の挙動は型クラスのインスタンス(MesShow)で制御したいというわけ。

ところが、この実装には問題がある(実際に上記コードはコンパイルが通らない)。

  • akkaのActorにおいてメッセージはAny型で渡されるのでRuntimeにしか型判定できない
  • traitの型パラメータはコンパイル時に型消去されるのでRuntimeでの判定には使えない

=> つまり、上記コードの「case m: MesType」という判定はできない、となる。

これを解決するためには、

  • Anyで渡ってくるメッセージはobj.getClassを経由してRuntimeにクラス情報を取得する
  • 型パラメータの方は、TypeTagを渡すことでRuntimeまでクラス情報を引き継ぐ

とやるしかない、と思う。たぶん。

で、書いてみたのが以下のコード。



TypeTagをわざわざ指定してやらないといけないところとか、asInstanceOfでダウンキャストしてるところとか、カッコ悪い。

というわけで、「こうやるともっと綺麗に書けるよ」とか、「そもそも方針としてこうやるべき」とかあったら教えてください!

0 件のコメント:

コメントを投稿