디자인패턴)MVC

소정·2023년 5월 26일
0

Kotlin

목록 보기
17/27

[0] 프로젝트 안에 모듈 만들기

데이터 분리 폴더 구조

[1] MVC 모델 [Model View controller]

  • 안드로이드에서 MVC 패턴은 컨트롤러와 View의 역할분리가 확실하지 않다

0. 데이터 바인딩 켜기

  • 그래이들에서 데이터 바인딩 쓴다고 명시하기

화면

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".controller.MainActivity">

    <EditText
        android:id="@+id/et_name"
        android:hint="이름"
        android:inputType="text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <EditText
        android:id="@+id/et_email"
        android:hint="이메일"
        android:inputType="textEmailAddress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/btn_save"
        android:text="save Data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/btn_load"
        android:text="load Data"
        android:backgroundTint="@color/teal_700"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="80dp"/>

    <TextView
        android:id="@+id/tv_result"
        android:text="result"
        android:textStyle="bold"
        android:textColor="@color/black"
        android:padding="8dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</androidx.appcompat.widget.LinearLayoutCompat>

1. Model

  • 데이터를 저장하는 클래스나 데이터를 DB또는 네트워크 등에서 불러오거나 저장하는 등의 작업을 하는 코드를 작성하는 파일
  • 데이터만 처리하는 친구

UserVO.kt

  • 데이터 클래스
package com.bsj0420.mvc.model

//이름 이메일 데이터 저장하는 역할의 데이터 클래스
data class UserVO(var name:String, var email:String)

UserModel.kt

  • 로직 처리 담당
package com.bsj0420.mvc.model

import android.content.Context
import androidx.core.content.edit

// 유저 정보(데이터)를 제어하는 기능 클래스
class UserModel constructor(val context: Context) { //데이터를 제어하기 위해서 콘텍스트 능력이 필요한 경우가 있다면 
    // 주 생성자로 전달 - 생성자 DI
    
    // 1) 데이터를 전달 받아서 SharedPreferences에 데이터 저장하는 기능
    fun saveData(name:String, email:String){

        val pref = context.getSharedPreferences("data", Context.MODE_PRIVATE)
        pref.edit {
            putString("name", name)
            putString("email", email)
        }

    }
    
    // 2) SharedPreferences에서 데이터를 읽어와서 내보내는(return) 기능
    fun loadData(): UserVO {
        val pref = context.getSharedPreferences("data", Context.MODE_PRIVATE)
        val name : String = pref.getString("name", "") as String //스트링으로 형변환
        val email : String =  pref.getString("email", "") as String

        return UserVO(name, email) //코틀린은 리턴 하나밖에 못함 그래서 모델을 사용하여 리턴
    }
    
}

2. View & Controller

View

  • 사용자가 볼 화면을 구현하는 목적의 코드가 있는 파일들 [activity_main.xml, MainActivity.kt , fragment.xml]

controller

  • 뷰와 모델 사이에서 연결하는 역할, 클릭 같은 이벤트를 처리하여 뷰의 요청에 따라 model 데이터를 제어하여 뷰에게 보여주는 역할
    [Activity.kt, Fragment.kt (이 둘은 View의 역할을 같이 함)]
  • 이벤트를 받아들이는 놈이 하는 것
  • 컨트롤러 역할을 Activity.kt, Fragment.kt가 함, 뷰와 컨트롤러를 완전히 분류할 수가 없음!
package com.bsj0420.mvc.controller

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.bsj0420.mvc.R
import com.bsj0420.mvc.databinding.ActivityMainBinding
import com.bsj0420.mvc.model.UserModel
import com.bsj0420.mvc.model.UserVO

class MainActivity : AppCompatActivity() {

    // 1. MVC 모델 [Model View controller]
    // 각 파일의 역할을 구분하여 작성하는 것이 특징
    // 1) Model
    // 데이터를 저장하는 클래스나 데이터를 DB또는 네트워크 등에서 불러오거나 저장하는 등의 작업을 하는 코드를 작성하는 파일 [item 클래스, retrofit 작업, db작업 클래스]

    // 2) View
    // 사용자가 볼 화면을 구현하는 목적의 코드가 있는 파일들 [activity_main.xml, MainActivity.kt , fragment.xml]

    // 3) controller
    // 뷰와 모델 사이에서 연결하는 역할, 클릭 같은 이벤트를 처리하여 뷰의 요청에 따라 model 데이터를 제어하여 뷰에게 보여주는 역할 
    // [Activity.kt, Fragment.kt (이 둘은 View의 역할을 같이 함)]
    // 컨트롤러 역할을 Activity.kt, Fragment.kt가 함, 뷰와 컨트롤러를 완전히 분류할 수가 없음!

    // app모듈에서 만든 Flat Design에서 MainActivity.kt에 작성한 코드들을 크게 3가지로 구분
    // #1 화면구현  -- view
    // #2 클릭 이벤트 처리 -- controller
    // #3 SharedPreferences를 이용하여 데이터를 저장하고 불러오는 비즈니스 로직을 가진 기능 -- model

    //역할 별 파일에 대한 구분을 쉽게 하기 위해 java폴더 안에 파일의 역할별로 패키지 나누기도 함

    //controller에선 참조변수 2개 필요
    // => view 와 model을 제어해야하기 때문!
    // view 역할을 하는 참조변수
    lateinit var binding : ActivityMainBinding

    // model 역할 참조변수
    lateinit var model : UserModel

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

        // # View 역할
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // # Model 객체 생성
        model = UserModel(this)

        // #controller 역할 - 클릭 이벤트 처리 [view model 연결작업 수행]
        binding.btnSave.setOnClickListener {
            model.saveData(binding.etName.text.toString(), binding.etEmail.text.toString())
        }

        binding.btnLoad.setOnClickListener {
            val userVo : UserVO = model.loadData()

            binding.tvResult.text = "${userVo.name} : ${userVo.email}"

        }

    
    }
}



📢 장단점

장점

  1. 데이터를 제어하는 코드가 Activity / Fragment 클래스 안에 모두 있지 않아서 간결해짐
  2. 역할 별로 코드가 분리되어 있어서 가독성이 좋고 기능 코드 위치를 식별하여 찾기 수월하여 유지보수 용이
  3. 모델 역할을 하는 클래스 안에 어떤 View도 참조하고 있지 않음!!!! -> view가 누구든 상관없음
    view를 변경해도 model의 코드는 전혀 변경되지 않기에 다른 view에서도 재사용 가능함

단점

  1. view와 controller 역할의 완전 분리가 어려움, Activity는 View이면서 controller 역할을 함
  2. view 에서 model 객체를 참조하고 있어서 model이 변경되면 view도 코드변하가 필요함
  3. 규모가 커지면 controller 역할을 하는 Activity의 코드는 여전히 비대해짐
profile
보조기억장치

0개의 댓글