[Android Studio] 아키텍처 패턴과 MVC 에 대하여.

hui·2023년 8월 13일

AndroidStudy

목록 보기
4/7

아키텍처 패턴

(Architecture Pattern)

아키텍처란, 시스템을 구성하는 서브 시스템, 컴포넌트와 같이 구성요소 간의 관계를 관리하는 시스템의 구조.
재사용 가능한 설계 원칙을 제공하여 유지 보수 가능하고 확장 가능한 시스템을 만드는데에 도움을 주며, MVC, MVP, MVMM 이 이에 속한다.

디자인 패턴과의 차이는 뭘까.

비슷하게 사용하는듯한 '디자인 패턴' 과 같은지 궁금해서 찾아보니 디자인 패턴은 주로 개별 클래스나 객체 간의 상호작용을 개선하는 데 사용되며, 코드 수준에서 적용되는 반면, 아키텍처 패턴은 전체 소프트웨어 시스템의 구조와 구성 요소 간의 관계를 설계하고, 시스템의 큰 틀을 결정하는 데 사용된다고 한다.

MVC

(Model-View-Controller)

모델은 애플리케이션의 정보(데이터)를 나타내며, 뷰는 텍스트, 체크박스 항목 등과 같은 사용자 인터페이스 요소를 나타내고, 컨트롤러는 데이터와 비즈니스 로직 사이의 상호동작을 관리한다.

  • Model
    Model은 Data와 애플리케이션이 무엇을 할 것인지를 정의하는 부분으로,
    컨트롤러가 호출을 하면 DB와 연동하여 사용자의 입출력 데이터를 다루는 일과 같은 데이터와 연관된 비즈니스 로직을 처리하는 역할을 한다. (데이터 추출, 저장, 삭제, 업데이트)

  • View
    View는 사용자에게 보여주는 화면 부분. 사용자와 상호작용 하며 컨트롤러로부터 받은 모델의 결과값을 화면으로 출력하는 역할을 한다.

  • Controller
    Controller는 Model과 View 사이를 이어주는 인터페이스로 Model이 데이터를 어떻게 처리할지 알려주는 역할이다. 사용자로부터 View에 요청이 있으면 Controller는 해당 일을 수행하는 Model을 호출하고 Model이 업무를 모두 수행하면 다시 결과를 View에 전달한다.

  • MVC패턴 사용의 장점과 단점.

    구현하기 쉽고 단순하며 모델과 뷰과 분리되어 모델의 비종속성으로 재사용이 가능하다.

    위 사진과 같이 모델과 뷰가 컨트롤러를 통해 상호작용하기 때문에 새로운 모델과 뷰를 조합하여 사용하는데 유연하지 못할 수 있다.

    스파게티 코드들을 양산하게 되고 단순하게 파악할 수 있다는 장점이 하나의 클래스에 집중이 되면서 단점으로 바뀔 수도 있다.


👉 예제

https://www.youtube.com/watch?v=FwFIKRpSElo 를 보고 만들었다.
지정해둔 비밀번호를 올바르게 눌러 넣었을시 성공 토스트 메세지를 띄우는 예제이다.

build.gradle에 데이터바인딩, 뷰바인딩 권한 활성화 시키기 필수.

1) 레이아웃 구성


<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center"
        tools:context=".MainActivity">

        <GridLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:columnCount="3"
            android:rowCount="3">

            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:onClick="@{()-> MainActivity.clickNumber(1)}" 
                android:text="1" />
                 <!--  @{..} ->  : 람다식을 사용하여 표현식을 정의한 것. 
            MainActivity 클래스의 clickNumber 메서드를 호출하고 인자로 1을 전달하는 코드-->

            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:onClick="@{()-> MainActivity.clickNumber(2)}"
                android:text="2" />

            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:onClick="@{()-> MainActivity.clickNumber(3)}"
                android:text="3" />

            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:onClick="@{()-> MainActivity.clickNumber(4)}"
                android:text="4" />

            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:onClick="@{()-> MainActivity.clickNumber(5)}"
                android:text="5" />

            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:onClick="@{()-> MainActivity.clickNumber(6)}"
                android:text="6" />

            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:onClick="@{()-> MainActivity.clickNumber(7)}"
                android:text="7" />

            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:onClick="@{()-> MainActivity.clickNumber(8)}"
                android:text="8" />

            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:onClick="@{()-> MainActivity.clickNumber(9)}"
                android:text="9" />
        </GridLayout>

        <TextView
            android:id="@+id/message_success"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="비밀번호 언락 성공"
            android:visibility="invisible" />

    </LinearLayout>
</layout>

그리드 레이아웃으로 금고모양 처럼 9개의 버튼 생성하였다.
후에 LinearLayout 위에 alt + enter를 눌러 데이터 태그를 만든다.
이 부분은 데이터 바인딩을 통해 XML 레이아웃 파일에서 사용될 변수를 정의한다.

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

        <variable
            name="MainActivity"
            type="com.example.a230811_mvvm.MainActivity" />
        <!--        xml레이아웃 파일에서 사용할 뷰 정의-->
    </data>
    <!--    데이터 바인딩(Data Binding) 라이브러리를 사용할 때 XML 레이아웃 파일에서 데이터와 뷰를 연결-->
    <!--    <variable> -> 뷰에서 사용될 변수 선언, 이름과 타입을 정함.  => 레이아웃 파일 내에서 뷰와 데이터를 연결하는데 사용.-->

2) MainActivity

//controller
class MainActivity : AppCompatActivity() {

    private lateinit var binding : ActivityMainBinding

    var model = Model()
    //모델 인스턴스 변수. 

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        //데이터바인딩을 사용해 현재 액티비티 컨텐츠뷰로 설정. 바인딩 -> UI요소와 액티비티 코드를 연결하는 객체가 됨.
        binding.mainActivity = this
        //데이터 바인딩으로 레이아웃을 변수랑 연결, mainActivity 변수를 현재 액티비티 객체로 설정.
    }


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

        if(model.password.size == 4 && model.checkPassword()) {
            //모델의 입력패스워드 사이즈가 4이고 입력한 패스워드가 일치할때
            binding.messageSuccess.visibility = View.VISIBLE
        }
    }

DataBindingUtil 클래스로 레이아웃을 설정하고 데이터 바인딩을 초기화한다.
현재 액티비티의 컨텍스트(this)와 레이아웃 리소스ID(R.layout.activity_main)를 전달받아 데이터 바인딩을 설정하고 바인딩 객체를 생성해 준다.

모델을 사용하는 부분은 모델 클래스 생성 후 작성하면 된다. -> mvc 패턴완성!

3) Model 클래스 생성

뷰를 표시해주는데 정보를 관리하는 일종의 클래스라 생각하면 쉽다.

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

//패스워드 사이즈가 4미만 일때까지 입력 수 추가 o
    fun inputPassword(i : Int) {
        if (password.size < 4) {
            password.add(i)
        }
    }
    
//정해 둔 비밀번호와 사용자가 입력한 비밀번호가 같은지 for문을 통해 
//숫자 하나하나 확인하고 trueCount가 4일시 true를 반환한다.

    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 += 1
            }
        }

        return trueCount == 4
    }
}

true를 반환하는 경우, 이 함수를 호출한 MainActivity로 돌아가 입력한 값의 사이즈와 trueCount가 같은지 확인하고 비밀번호 언락 성공 텍스트뷰를 보이도록 한다.

👉 마무리

데이터 태그 출현에 버벅거리는걸 보아선 다시 한 번 복습해야겠다.
남은 MVP, MVMM 아키텍처 패턴도 예제랑 같이 정리해보기를 목표로 하며.. zz

profile
백엔드 개발자로 변신.

1개의 댓글

comment-user-thumbnail
2023년 8월 13일

감사합니다. 이런 정보를 나눠주셔서 좋아요.

답글 달기