[Android] 아키텍처 패턴

이유빈·2023년 9월 6일
0

Study

목록 보기
3/4
post-thumbnail

MVC

  • Model(모델): 데이터 로직을 처리하는 부분
  • View(뷰): 사용자에게 보이는 UI 부분
  • Controller(컨트롤러): 사용자의 입력을 받고 처리하는 부분

MVC는 가장 기본적인 패턴이라고 할 수 있다.
사용자의 액션을 Controller로 받고 Model을 업데이트 한다. Controller는 Model을 나타낼 View를 선택하고 View는 이를 이용해 화면에 나타낸다.

그럼 이를 코드로 알아보자!😆
비밀번호 4개를 입력했을 때 언락(unlock)이 됐다는 텍스트를 표시하는 예시이다.
여기서 MainActivity가 Controller의 역할을 한다.

MainActivity.kt 파일입니다.

// Controller
class MainActivity : AppCompatActivity() {

    lateinit var binding : ActivityMainBinding

    var model = Model()

    override fun onCreate(savedInstanceState: Bundle?){
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        binding.mainActivity = this
    }

    fun clickNumber(i :Int){
        Toast.makeText(this, "$i 번을 클릭했습니다.", Toast.LENGTH_SHORT).show()
        model.inputPassword(i)

        if(model.password.size == 4 && model.checkPassword()){
            // 4자리 이상 비밀번호가 1234
            binding.messageSuccess.visibility = View.VISIBLE
        }
    }
}

Model.kt 파일입니다.

class Model {
    var password : MutableList<Int> = mutableListOf()

    fun inputPassword(i : Int){
        if(password.size < 4){
            password.add(i)
        }
    }
    fun checkPassword() : Boolean{
        var trueCount = 0
        var savePassword = mutableListOf(1,2,3,4)

        for (i in 0 until savePassword.size){
            if(savePassword.get(i)==password.get(i)){
                trueCount++
            }
        }

        return trueCount == 4
    }
}

앞으로 나올 코드의 UI는 모두 아래 사진과 같습니다.


MVP

  • Model(모델): 데이터 로직을 처리하는 부분
  • View(뷰): 사용자에게 보이는 UI 부분
  • Presenter(프레젠터): View에서 요청한 정보를 Model로부터 가공하여 View로 전달하는 부분

Presenter가 View와 Model을 제어한다.
Model이 View를 직접적으로 제어할 수 없는 것이 MVC와의 차이점이다.
Controller는 단순히 정보만 입력받는 interface로 변환된다.
다른 Activity가 생겼을 때 Presenter를 손쉽게 이식할 수 있다는 장점을 가지고 있다.

그럼 MVP도 코드로 알아보자!😍
MVC와는 다르게 interface파일이 추가되었다.

MainActivity.kt 파일입니다.

class MainActivity : AppCompatActivity(), ViewInterface{

    lateinit var binding : ActivityMainBinding

    var presenter = Presenter(this)

    var model = Model()

    override fun onCreate(savedInstanceState: Bundle?){
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        binding.mainActivity = this
    }

    fun clickNumber(i :Int){
        presenter.clickNumber(i)
    }

    override fun toastMessage(i: Int) {
        Toast.makeText(this, "$i 번을 클릭했습니다.", Toast.LENGTH_SHORT).show()
    }

    override fun checkPasswordMessage() {
        binding.messageSuccess.visibility = View.VISIBLE
    }
}

Model.kt 파일은 MVC와 동일합니다.

Presenter.kt 파일입니다.

class Presenter(var viewInterface : ViewInterface) {
    var model = Model()

    fun clickNumber(i :Int){
        viewInterface.toastMessage(i)
        model.inputPassword(i)

        if(model.password.size == 4 && model.checkPassword()){
           viewInterface.checkPasswordMessage()
        }
    }
}

ViewInterface.kt 파일입니다.

interface ViewInterface {
    fun toastMessage(i : Int)
    fun checkPasswordMessage()
}

MVVM

앞서 설명했던 MVC와 MVP를 보완하기 위해 MVVM이 나왔다.

  • Model(모델): 데이터 로직을 처리하는 부분
  • View(뷰): 사용자에게 보이는 UI 부분
  • Vew Model(뷰 모델): View에서 사용되는 데이터를 관리하는 View를 위한 Model

여러 개의 뷰를 연결할 수 있는 것이 MVP와의 차이점이다.
여러 개를 연결하게 되면 Presenter가 아니라 View Model이라고 부르는 것이다.

MVVM도 코드로 이해해보자!🙂

MainActivity.kt 파일입니다.

class MainActivity : AppCompatActivity(){

    lateinit var binding : ActivityMainBinding
    var viewModel = ViewModel()

    override fun onCreate(savedInstanceState: Bundle?){
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        binding.viewModel = viewModel
        viewModel.toastMessage.observe(this, Observer{i ->
            Toast.makeText(this, "$i 번을 클릭했습니다.", Toast.LENGTH_SHORT).show()
        })
        viewModel.checkPasswordMessage.addOnPropertyChangedCallback(object : Observable.OnPropertyChangedCallback(){
            override fun onPropertyChanged(sender: Observable?, propertyId: Int) {
                if(viewModel.checkPasswordMessage.get() == true){
                    binding.messageSuccess.visibility = View.VISIBLE
                }else{
                    binding.messageSuccess.visibility = View.GONE
                }
            }
        })
    }
}

Model.kt 파일입니다.

class Model {
    var password : MutableList<Int> = mutableListOf()

    fun inputPassword(i : Int){
        if(password.size < 4){
            password.add(i)
        }
    }
    fun checkPassword() : Boolean{
        var trueCount = 0
        var savePassword = mutableListOf(1,2,3,4)

        for (i in 0 until savePassword.size){
            if(savePassword.get(i)==password.get(i)){
                trueCount++
            }
        }

        return trueCount == 4
    }
}

ViewModel.kt 파일입니다.

class ViewModel {
    var toastMessage = MutableLiveData<Int>()
    var checkPasswordMessage = ObservableField<Boolean>(false)

    var model = Model()

    fun clickNumber(i :Int){
        toastMessage.value = i
        model.inputPassword(i)

        if(model.password.size == 4 && model.checkPassword()){
            // 비밀번호가 맞을 경우 True
            checkPasswordMessage.set(true)
        }
    }
}

즉, 아래와 같이 변수로 선언해서 사용하면 다중 뷰를 무한히 연결시켜서 사용할 수 있는 것이다.

var checkPasswordMessage = ObservableField<Boolean>(false)
profile
Computer Science && Engineering

0개의 댓글

관련 채용 정보