개발/Android

[Kotlin/코드] MVP 패턴

레란희 2022. 2. 14. 13:37

두 수를 입력받아 합을 출력하는 간단한 프로그램이다.

 

# 전체 구조

 

0. layout

- EditText 두 개, Button 하나, TextView 하나로 구성

 

 

1. MyApplication

package com.monkey.mvpstudy

import android.app.Application
import android.content.Context
import android.content.SharedPreferences

class MyApplication : Application() {
    companion object {
        lateinit var context: Context
        lateinit var pref: SharedPreferences
    }

    init {
        context = this
    }
}

- SharedPrefence를 사용하기 위해서 사용

- Manifest의 <application> 태그 내에 android:name=".Myapplication"으로 사용

 

 

2. Contract

package com.monkey.mvpstudy

interface Contract {
    interface View {
        fun setValue(num1: Int, num2: Int, num3: Int)
        fun showResult(num: Int)
    }

    interface Presenter {
        fun getSum(num1: Int, num2: Int)
        fun save(num1: Int, num2: Int)
        fun load()
    }
}

- 뷰단에서는 값을 설정하고 결과를 보여주도록 할 것이다.

- 프레젠터단에서는 합을 구하고 저장하고 불러오도록 할 것이다.

 

 

3. MainModel

package com.monkey.mvpstudy

class MainModel {
    val presenter: Contract.Presenter

    constructor(presenter: Contract.Presenter) {
        this.presenter = presenter
    }

    fun getSum(num1: Int, num2: Int): Int {
        return num1+num2
    }
}

- 모델에서는 프레젠터를 참고하고 있음

- getSum이라는 함수로 합계를 구하도록 하였음

 

 

4. MainActivity

package com.monkey.mvpstudy

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.monkey.mvpstudy.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity(), Contract.View {
    val binding by lazy {
        ActivityMainBinding.inflate(layoutInflater)
    }
    val presenter by lazy {
        MyPresenter(this)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        MyApplication.pref = getSharedPreferences("myApp", MODE_PRIVATE)

        presenter.load()    //SharedPreference에 저장한 값을 세팅

        binding.btnOk.setOnClickListener {
            val num1 = binding.etNum1.text.toString().toInt()
            val num2 = binding.etNum2.text.toString().toInt()
            presenter.getSum(num1, num2)
            presenter.save(num1, num2)
        }
    }

    override fun setValue(num1: Int, num2: Int, num3: Int) {
        binding.etNum1.setText(num1.toString())
        binding.etNum2.setText(num2.toString())
        showResult(num3)
    }

    override fun showResult(num: Int) {
        binding.tvResult.text = num.toString()
    }
}

- 맨 처음 onCreate 호출 시 저장한 값을 불러오도록 함

- 버튼을 누르면 presenter에게 합을 구하고 값을 저장하도록 함

- Contract의 View를 상속받았으므로 setValue와 showResult 구현

 

 

5. MyPresenter

package com.monkey.mvpstudy

import androidx.core.content.edit

class MyPresenter : Contract.Presenter {
    companion object {
        val _P_NUMBER1 = "number1"
        val _P_NUMBER2 = "number2"
    }
    var view : Contract.View
    var model : MainModel

    constructor(view: Contract.View) {
        this.view = view
        this.model = MainModel(this)
    }

    override fun getSum(num1: Int, num2: Int) {
        val sum = model.getSum(num1, num2)
        view.showResult(sum)
    }

    override fun save(num1: Int, num2: Int) {
        MyApplication.pref.edit {
            putInt(_P_NUMBER1, num1)
            putInt(_P_NUMBER2, num2)
        }
    }

    override fun load() {
        val num1 = MyApplication.pref.getInt(_P_NUMBER1, 0)
        val num2 = MyApplication.pref.getInt(_P_NUMBER2, 0)
        val sum = model.getSum(num1, num2)
        view.setValue(num1, num2, sum)
    }
}

- Contract의 Presenter을 상속받아 getSum, save, load를 구현

- getSum은 코드의 중복과 확장성을 위해 model의 getSum으로 로직을 옮김