※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)みたいに呼びだすことができたので、問題はなさそうかなと。
全部委譲したくない場合はどうするんだろうか?
最初のようにやっていくのかな?
