※2013/07/12現在、これをやると、処理は委譲できるんだけど、IntelliJのコード補完が死ぬみたいなので、オススメできないです。すみません。
== 以下、原文。
Kotlinのサイトで委譲(Delegation)の説明があるのだけれど、その方法が、渡された引数にたいしてのものだったのでよくわからなかった。というかそのパターンはそうなんだろうけど、俺がやりたいのはそうじゃないんだよ、ってことだった。
いま、KotlinでORMLiteを使っていて、DAOの実装をテーブル単位で行いたいからどうしようかなと思っていた。
とりあえず、DAOクラスはシングルトンでよかろうと思ってobjectで実装していた。
まずDatabaseHelperのソース。
Delegates.lazyを使って遅延評価してる。使われるときになってDBに接続するようにしてみた。
Userはエンティティクラスなので記載を省略する。
object DatabaseHelper { val connectionSource by Delegates.lazy { val databaseUrl = "jdbc:h2:~/test" JdbcConnectionSource(databaseUrl) }; { setUpDatabase(connectionSource) } private fun setUpDatabase(connectionSource: ConnectionSource) { TableUtils.createTableIfNotExists(connectionSource, javaClass<User>()) } fun getUserDao() : Dao<User, Int> = DaoManager.createDao(connectionSource, javaClass<User>())!! fun close() = connectionSource.close() }
次に、UserDaoクラスを作った。
object UserDao { public val dao : Dao<User, Int> by Delegates.lazy { DatabaseHelper.getUserDao() } fun existsUser(user: User) : Boolean { val where = dao.queryBuilder()!!.where()!! if (user.id != null) { where.ne(User.ID, user.id)!!.and() } return where.eq(User.EMAIL, user.email)!!.countOf() > 0 } fun create(user: User) { dao.create(user) } }
このcreateメソッドが、daoに処理を任せている。update,deleteなど、これからたくさん同じようなことが起きるので、daoプロパティに処理を任せてしまいたい。
そう思ってDeletationを調べだした。で、最終的にたどり着いたコードがこちら。
object UserDao : Dao<User, Int> by DatabaseHelper.getUserDao() { fun existsUrl(user: User) : Boolean { val where = queryBuilder()!!.where()!! if (user.id != null) { where.eq(User.ID, user.id)!!.and() } return where.eq(User.URL, user.url)!!.countOf() > 0 } }
クラス名の後ろにbyを付ける事で、委譲対象を指定できるようだ。別に引数で受け取ったインスタンスである必要もないみたいだ。
まぁ正しいやり方かどうかってのが怪しい。。。
しかし、これでUserDao.create(user)みたいに呼びだすことができたので、問題はなさそうかなと。
全部委譲したくない場合はどうするんだろうか?
最初のようにやっていくのかな?