Kotlinでクラスの処理を委譲する

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


タグ Kotlin | パーマリンク.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です