CS/Basic

[CS Basic] MVC Pattern

Bell91 2023. 12. 21. 17:39
반응형

1. MVC Pattern 이란?

주로 UI관련된 복잡한 앱에서 많이 사용된다. 즉 View의 업데이트가 주가 될 때 사용된다고 보면 된다. 각 요소의 분리된 코드로 Controller 에서 입력을 받아 각 Model과 View를 업데이트 해준다. 즉 MainActivity에서 입력받아 컨트롤러로 이동하고 그 다음 구조가 하위의 다음 그림과 같다.

 

(1) 예시1

  • Model 모델 : 데이터와 로직 담당, 서버에서 데이터를 가져오는 공간
  • View 뷰 : 사용자 인터페이스를 표시, 모델의 상태를 UX로 표시
  • Controller 컨트롤러 : 엑티비티를 통해 입력받은 값을 뷰나 모델에 데이터를 전달해준다.

 

(2) 예시2

  • 사용자 Action이  controller로 들어온다
  • Controller는 Action 에 맞는 데이터 처리를 Model에 요청 및 갱신
  • Controller는 Model을 통해 View를 갱신

Activity에서  View를 바인딩하는 안드로이드구조에 따라 어쩔 수 없이 View와 Controller(Activity)가 공존하게 될수도 있다.

 

2. Code

(1) Model

데이터 형식 지정, 서버에서 데이터를 가져오는 곳

public class UserModel {
    private String username;
    private String email;

    public String getUsername() {
        return username;
    }

    public String getEmail() {
        return email;
    }

    public void fetchDataFromServer(Callback<UserModel> callback) {
        // Retrofit을 사용하여 서버에서 데이터 비동기적으로 가져오기
        ApiService apiService = RetrofitClient.getApiService();
        Call<UserModel> call = apiService.getUserData();

        call.enqueue(new Callback<UserModel>() {
            @Override
            public void onResponse(Call<UserModel> call, Response<UserModel> response) {
                if (response.isSuccessful()) {
                    UserModel userModel = response.body();
                    // 서버에서 받아온 데이터로 모델 업데이트
                    setUser(userModel.getUsername(), userModel.getEmail());
                    callback.onResponse(call, response);
                } else {
                    // 서버에서 오류 응답을 받았을 때의 처리
                    callback.onFailure(call, new Throwable("Server error"));
                }
            }

            @Override
            public void onFailure(Call<UserModel> call, Throwable t) {
                // 네트워크 오류 또는 예외 처리
                callback.onFailure(call, t);
            }
        });
    }

    public void setUser(String username, String email) {
        this.username = username;
        this.email = email;
    }
}

 

(2) Controller

사용자 입력을 받아 처리, 모델이나 뷰의 상태 변경

public class UserController {
    private UserModel userModel;
    private MainActivity mainActivity;

    public UserController(UserModel userModel, MainActivity mainActivity) {
        this.userModel = userModel;
        this.mainActivity = mainActivity;
    }

    public void fetchDataFromServer() {
        // 모델을 통해 서버에서 데이터 가져오기
        userModel.fetchDataFromServer(new Callback<UserModel>() {
            @Override
            public void onResponse(Call<UserModel> call, Response<UserModel> response) {
                // 뷰 업데이트
                mainActivity.onUserModelUpdated(userModel.getUsername(), userModel.getEmail());
            }

            @Override
            public void onFailure(Call<UserModel> call, Throwable t) {
                // 오류 처리
                mainActivity.showError("Failed to fetch data");
            }
        });
    }
}

 

(2) View

사용자에게 UX를 제공한다.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/fetchDataButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fetch Data" />

    <TextView
        android:id="@+id/usernameTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/fetchDataButton"
        android:text="Username: "/>

    <TextView
        android:id="@+id/emailTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/usernameTextView"
        android:text="Email: "/>
</RelativeLayout>

 

(4) Activity

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

    private TextView usernameTextView;
    private TextView emailTextView;
    private UserController userController;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 뷰 컴포넌트 초기화
        usernameTextView = findViewById(R.id.usernameTextView);
        emailTextView = findViewById(R.id.emailTextView);
        Button fetchDataButton = findViewById(R.id.fetchDataButton);

        // 모델 및 컨트롤러 초기화
        UserModel userModel = new UserModel();
        userController = new UserController(userModel, this);

        // 버튼 클릭 이벤트 처리
        fetchDataButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 컨트롤러를 통해 서버에서 데이터 가져오기
                userController.fetchDataFromServer();
            }
        });
    }

    public void onUserModelUpdated(String username, String email) {
        // 뷰 업데이트
        usernameTextView.setText("Username: " + username);
        emailTextView.setText("Email: " + email);
    }

    public void showError(String errorMessage) {
        // 오류 메시지를 표시하는 뷰 업데이트
        // 이 부분은 실제 애플리케이션에서는 사용자에게 보여주는 방식에 따라 다를 수 있음
    }
}

 


Reference

https://academy.realm.io/kr/posts/eric-maxwell-mvc-mvp-and-mvvm-on-android/

https://moon-i.tistory.com/entry/Android-%EC%97%90%EC%84%9C-MVC-MVP-MVVM-%EC%98%88%EC%A0%9C%EB%A1%9C-%EA%B3%B5%EB%B6%80%ED%95%98%EA%B8%B0

반응형