【kotlin】超簡単なMVPを実装してみた、①Presenterの実装

# MVPとは?
Androidアーキテクチャの一つ。
ActivityやFragmentで行っていた処理を以下の三つの役割に分ける。

・Model(データに関する処理を行う)
・View(画面に関する処理、クリック等のイベントを拾ってPresenterに送る処理を行う)
・Presenter(Viewからイベントを受け取り、Modelを操作したり、Viewに伝え画面操作を行うロジカルな処理を行う)

**[メリット]**
・Activity,Fragmentの肥大化を防げる。
・テストがしやすい。

# 実装内容
Presenterまで実装する。
EditTextに文字を入力してボタンを押したら、下部のTextViewに表示させる(超簡単)。
![presenter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784089/327d668f-79fd-381d-ac6a-bec60fe05c83.png)

# 実装
**[レイアウト]**
①editText
②button
③textView
![presenterのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784089/454cf019-aae6-2ece-6d36-ea7a8186396b.png)

**[コード]**
**・準備**
①BasePresenter,BaseViewを作成。

```kotlin:BasePresenter
interface BasePresenter {
　    //起動処理のメソッド
    fun start()
}
```

```kotlin:BaseView
interface BaseView<T> {
    var presenter: T
}
```
**・Contract設定**
※Contractの役割はViewとPresenterを橋渡し、双方で使用するメソッドを定義する。
①Contractを作成。
②interface Viewとinterface Presenterを作成(戻り値にBasePresenter、BasePresenterを追加)。
③viewとpresenterで使用するメソッドを作成。

```kotlin:MainContract
interface MainContract {

    interface View: BaseView<Presenter> {
        //③textViewをテキストを表示するメソッド
        fun showTextView (text: String)

    }

    interface Presenter: BasePresenter {
        //③Butoonをクリックされた際に使用するメソッド
        fun onClickButton(text: String)

    }
}
```
**・Presenter設定**
①Presenter作成。
②Contract.View(MainContract.View)を引数に追加。
③Contract.presenter(MainContract.Presenter)を戻り値に追加。
④view.presenter = thisに設定(view側で設定しないと出来ないかもしれない)。
⑤Contractで作成したメソッドが色々出てくるので設定。

```kotlin:MainPresenter
class MainPresenter(private val view: MainContract.View): MainContract.Presenter {

    //④view.presenter = thisに設定
    init {
        view.presenter = this
    }

    //⑤起動処理
    override fun start() {
    }

    //⑤ボタンが押された時の処理
    override fun onClickButton(text: String) {
        view.showTextView(text)
    }

}
```
**・View設定**
①View(Activity、Fragment)の戻り値にContract.View(MainContract.View)を追加。
②overrideしたContract.presenter(MainContract.Presenter)を追加。
③起動時にpresenterをインスタンス化。
④Contractで作成したメソッドが色々出てくるので設定(showTextView())。
⑤presenterのメソッドを呼び出す

```kotlin:MainFragment
class MainFragment: Fragment(),MainContract.View {
    //②overrideしたContract.presenter(MainContract.Presenter)を追加。
    override lateinit var presenter: MainContract.Presenter
    lateinit var editText :EditText
    lateinit var button :Button
    lateinit var textView :TextView

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_main, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        editText = view.findViewById<EditText>(R.id.editTextText)
        button = view.findViewById<Button>(R.id.button)
        textView = view.findViewById<TextView>(R.id.textView)

        //③起動時にpresenterをインスタンス化
        initPresenter()

        //⑤presenter.startを呼び出す。
        presenter.start()

        button.setOnClickListener{
            //⑤presenter.onClickButtonを呼び出す。
            presenter.onClickButton(editText.text.toString())
        }
    }
    //④TextViewに文字を表示させる
    override fun showTextView(text: String) {
        textView.text = text
    }

    fun initPresenter() {
        if (::presenter.isInitialized) {
            return
        }
        presenter = MainPresenter(this)
    }
}
```
以上、Presenterの実装でした。

# 関連記事
[【kotlin】超簡単なMVPを実装してみた、②LocalRepository設定(ローカルデータに保存、読み込み)](https://qiita.com/Na0yaKub0/items/7209258a0d7b084d276a)
[【kotlin】超簡単なMVPを実装してみた、③RemoteRepository設定(APIのやり取り)](https://qiita.com/Na0yaKub0/items/57358d689b6552ad7d75)

# 参考資料
[Android アプリ設計パターン入門](https://peaks.cc/books/architecture_patterns)
[テストが書けない人のAndroid MVP](https://www.amazon.co.jp/%E3%83%86%E3%82%B9%E3%83%88%E3%81%8C%E6%9B%B8%E3%81%91%E3%81%AA%E3%81%84%E4%BA%BA%E3%81%AEAndroid-MVP-%E6%8A%80%E8%A1%93%E3%81%AE%E6%B3%89%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%EF%BC%88NextPublishing%EF%BC%89-%E9%AB%98%E7%95%91-%E5%8C%A1%E7%A7%80/dp/4844398717)
[todo-mvp](https://github.com/android/architecture-samples/tree/todo-mvp-kotlin/todoapp)