소프트웨어 패턴중 하나입니다.
최근 MVVM으로 구성되지 않은 앱을 찾기 어려울정도로 대중화가 되어있기 때문에 MVVM으로 가는
발판으로 생각하고 포스팅을 시작합니다.
먼저 명명부터 알아봅시다.
Model - View - Presenter로 구성되어 있습니다.
Model
View
Presenter
Presenter는 View와 Model의 인스턴스를 가지고 있어 둘을 연결하는 접착제 역할을 합니다.
Presenter와 View는 1:1 관계입니다.
MVP 패턴의 장점은 View와 Model의 의존성이 없다는 것입니다. MVP 패턴은 MVC 패턴의 단점이었던 View와 Model의 의존성을 해결하였습니다.
MVC 패턴의 단점인 View와 Model 사이의 의존성은 해결되었지만, View와 Presenter 사이의 의존성이 높은 가지게 되는 단점이 있습니다. 어플리케이션이 복잡해 질 수록 View와 Presenter 사이의 의존성이 강해지는 단점이 있습니다.
interface Contract {
//View와 Presenter 에서 필요한 메소드들을 가지고있음 interface
interface View {
fun setCalcResult(res: Int)
fun getFirstNum(): Int
fun getSecondNum(): Int
}
interface Presenter {
fun calc(x: Int, y: Int, type: Char)
}
}
뷰 - 클릭을 받아들이고 프레젠터로 입력값을 보낸다.
계산은 프레젠터에게 맡긴다.
프레젠터에서 뷰의 값을 받아서 계산할수 있도록 Presenter를 생성해준다.
그리고 Contract 인터페이스를 이용하여 결과값을 세팅해준다.
//View부분.
//presenter를 갖고있으며 , View를 상속받음.
class MainActivity : AppCompatActivity(), Contract.View {
lateinit var binding : ActivityMainBinding
val presenter by lazy { MainPresenter(this) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.plus.setOnClickListener{
presenter.calc(getFirstNum(),getSecondNum(),'+')
}
binding.minus.setOnClickListener{
presenter.calc(getFirstNum(),getSecondNum(),'-')
}
binding.divide.setOnClickListener{
presenter.calc(getFirstNum(),getSecondNum(),'/')
}
binding.multiply.setOnClickListener{
presenter.calc(getFirstNum(),getSecondNum(),'*')
}
}
override fun setCalcResult(res: Int) { binding.result.text = res.toString() }
override fun getFirstNum(): Int = binding.leftValue.text.toString().toInt()
override fun getSecondNum(): Int = binding.rightValue.text.toString().toInt()
}
프레젠터 - 실질적인 데이터 계산을 하는 곳
데이터의 결과값을 view.setCalcResult를 한다.
View와의 통신을 하기 위해서 매개변수로 view를 가지고 있는다.
calc라는 메소드는 view에서 받아온 값들을 계산해주고, view에게 다시 setCalcResult를 돌려준다.
view.setCalcResult(res)는 Contract.View에 들어있다.
메인액티비티에서 오버라이딩하여 값을 xml에 보여준다.
class MainPresenter(val view: Contract.View) : Contract.Presenter {
//View에서 보여줄 값들을계산함.
override fun calc(x: Int, y: Int, type: Char) {
val res = when (type) {
'+' -> x + y
'-' -> x - y
'*' -> x * y
'/' -> x / y
else -> 0
}
view.setCalcResult(res)
}
}