※ MVC(Model - View - Controller)

- Model : 데이터에 관한 영역으로 DB 등 데이터 저장소에 접근해 데이터를 검색, 삽입, 삭제, 수정하는 영역이다.

- View : 사용자에게 보여질 화면에 관한 영역이다.

- Controller : Model과 View 사이에 위치한 영역으로 사용자의 요청을 받은 후 Model에 접근해 데이터를 비즈니스 로직에 따라 처리하고 그에 해당하는 결과를 보여줄 View를 선택해 View에 처리 결과를 제공한다.



- 안드로이드에서 MVC 패턴 구현 


:Activity/Fragment가 Controller(예를 들어, 사용자의 터치 이벤트를 받아 데이터에 접근 후 처리)와 View(예를 들어, 화면 갱신) 역할을 한다. => Activity/Fragment에서 데이터 접근, 화면 갱신, 로직 처리 등을 해 Activity/Fragment 클래스의 크기가 방대해지고 유지 보수가 힘들어진다. => Mvvm 패턴 등장



public class MainAcivity extends Activity {
	private MainModel mainModel;

	@Override
	public void onCreate(Bundle saveInstance) {
		super.onCreate(saveInstance);
		setContent(R.layout.main);
		
		mainModel = new MainModel();
		
		TextView textView = (TextView) findViewById(R.id.btn_confirm);
		textView.setText("Non-Clicked");
		
		
		findViewById(R.id.btn_confirm)
			.setOnClickListener(new View.OnClickListener(){
			
				@Override
				public void onClick(View view) {
					String text = mainModel.getClickedText();
					TextView textView = (TextView) findViewById(R.id.btn_confirm);
					textView.setText(mainModel.getClickedText());
				}
			});
	}
}


public class MainModel {
	public String getClickedText() {
		return "Clicked!!!";
	}
}

mvc 패턴을 이용한 위 코드는 View와 상관 없는 로직을 MainModel로 분리했다. Activity는 사용자의 클릭 이벤트를 받아 처리하는 Controller 역할을 하고 View에 직접 접근도 한다. 이렇게 Activity는 View와 Controller의 역할을 동시에 해 mvc 패턴에 어긋난다.



※ MVVM(Model - View - ViewModel)

: ViewModel이 View와 모델에 접근해 Controller 역할을 수행하는 것으로 이 패턴은 Activity가 매개변수로 ViewModel에 넘어갈 만큼 Activity가 하는 일이 사라지는 단점이 있다.


public class MainAcivity extends Activity {
	private MainViewModel mainViewModel;
	@Override
	public void onCreate(Bundle saveInstance) {
		super.onCreate(saveInstance);
		setContent(R.layout.main);
		
		mainViewModel = new MainViewModel(MainActivity.this);	
	}
}


public class MainModel {

	public String getClickedText() {
		return "Clicked!!!";
	}
}


public class MainViewModel {

	private Activity activity;
	private MainModel mainModel;
	private TextView textView;
	
	public MainViewModel(Activity activity) {
		this.activity = activity;
		this.mainModel = new MainModel();
		initView(activity);
	}

	private void initView(Activity activity) {
	
		textView = (TextView) activity.findViewById(R.id.btn_confirm);
		textView.setText("Non-Clicked");
	
		activity.findViewById(R.id.btn_confirm)
			.setOnClickListener(new View.OnClickListener(){
			
				@Override
				public void onClick(View view) {
					String text = mainModel.getClickedText();
					textView.setText(text);
				}
			});
	}
}

mvvp 패턴을 이용한 위 코드는 Activity가 mvc 패턴과 달리 Controller의 역할을 수행하지 않고, 온전히 View의 역할을 수행한다. 또한, ViewModel에서 Model에 접근해서 모든 처리를 하고 View의 화면을 갱신한다. 그런 만큼 View에 대한 처리가 많아질수록 ViewModel의 크기가 커지고 그에 비해 Activity는 일을 거의 하지 않는 상황이 발생할 수 있다.



※ MVP(Model - View - Presenter)

- View에서 사용자의 반응을 받으면 해당 정보를 Presenter에 넘기고 Presenter은 받은 정보를 토대로 Model에게 정보에 대한 처리를 부탁한다. Model은 결과를 presenter에게 주고 Presenter가 View에게 결과를 가지고 갱신하라고 한다. 그러면 최종적으로 View가 갱신된다. 이렇게 Presenter는 Model과 View를 이어주는 다리 역할을 한다.


- mvc의 경우 사용자의 요청이 Controller에게 가는데 mvp는 View에게 간다. 안드로이드에서 mvc 패턴을 사용하기 애매한 이유가 사용자의 요청이 View 즉, Acitivity에게 가기 때문에 View가 Controller의 역할도 하기 때문이다.



public interface MainContract {
    interface Presenter{
        void setView(MainContract.View view);
        void setModel(MainModel model);
        void onConfirm();
    }
    interface View{
        void showButtonText(String text);
    }
}


public class MainPresenter implements MainContract.Presenter {

    MainModel mainModel;
    MainContract.View view;

    @Override
    public void setView(MainContract.View view) {
        this.view = view;
    }

    @Override
    public void setModel(MainModel model) {
        this.model = model;
    }

    @Override
    public void onConfirm() {
        view.showButtonText(mainModel.getClickedText());
    }
}


public class MainModel {
    public String getClickedText() {
        return "Clicked!!!";
    }
}


ublic class MainActivity extends AppCompatActivity implements MainContract.View {

    private Button confirmBtn;
    private MainPresenter presenter;
    private MainModel model;

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

        presenter = new MainPresenter();
        presenter.setView(this);
        model = new MainModel();
        presenter.setModel(model);

        confirmBtn = (Button) findViewById(R.id.btn_confirm);
        confirmBtn.setOnClickListener(new View.OnClick() {
            @Override
            public void onClick(View view) {
                presenter.onConfirm();
            }
        });

    }

    @Override
    public void showButtonText(String text) {
        confirmBtn.setText(text);
    }
}


위 코드가 mvp 패턴을 적용한 예이다. 구체적인 안드로이드 mvp 패턴에 대해서는 안드로이드 다음 포스트 "안드로이드 mvp"에 있다. 

'안드로이드 > 기본' 카테고리의 다른 글

NDK(1) - JNI, Android.mk  (0) 2017.06.30
안드로이드 mvp  (0) 2017.06.15
SharedPreferences  (0) 2017.06.04
action.Main, category.LAUNCHER  (0) 2017.06.04
메인 화면을 single_top, clear_top으로 하자  (0) 2017.06.04

+ Recent posts