TRY ANDROID DEV

Android アプリ開発のコーディングネタ。あとエンジニアとしての活動

Kotlinでprivate constructorを利用する(companion object)

背景

  • static public な文字列を定義したくなった。(途中で思い返して異なる方法をとったけれど。)

内容

以下のような形でdomainに文字列を設定していたが、利用可能なドメインは限られているため、いくつかの固定文字列から選択させる形を取ろうとした。

fun getNovelList(word: String): List<NovelIntroduction> {
        val webSite = DaggerDomainComponent.builder()
            .domain("https://api.syosetu.com/")  < ここを定数定義する
            .build() // DomainComponentを生成する
            .inject() // inject実施。repositoryを注入する。

        return webSite.search(word)
    }

でもよく考えたらこうしても別に他のStringを注入できるし、あんまり意味ない。 結論として以下のようにprivate constructorを利用して、生成できるドメインを制限した。

class WebSite private constructor(
        val domain: String,
        private val searchRepository: ISearchRepository = DaggerRepositoryComponent.create().makeSearchRepository(),
        private val getPageRepository: IGetPageRepository = DaggerRepositoryComponent.create().makeGetPagePepository()
) {

    companion object {
        fun accessNarou(): WebSite {
            return WebSite("https://yomou.syosetu.com/")
        }
    }

    fun search(word: String): List<NovelIntroduction> {
        return searchRepository.search(word)
    }

    fun getIndex(ncode: String): Single<Contents> {
        return getPageRepository.getIndex(ncode)
    }
}

private constructorの実装としては以下の2手順で良い。

  1. constructorにprivateをつける
  2. companion object で自身を返却するメソッドを作成する。

ここでcompanion object がjavaで言う所のstatic なメソッドの指定となる。
ただし、javaのstatic宣言とは異なり、実体オブジェクトのインスタンスメンバーなのでinterfaceを実装できるらしい。
(今の所用途があんまり見えないけど。。) インスタンス生成時に実体を選択できるのはDI的に良いのかも。

javaのstaticにしたい場合は@JvmStaticというアノテーションをつけるといいらしい。

参照