SlideShare a Scribd company logo
1 of 41
Download to read offline
MVP 패턴 소개 (안드로이드)
신림프로그래머, 최범균, 2016-06-18
madvirus@madvirus.net
다룰 내용
• 막 만들면
• MVP 패턴
– 적용 결과
• MVP 패턴 적용 예
– 안드로이드
– 자바스크립트
• 정리
2
간단한 앱, 막 만들면…
3
드래그 탭
미림분식
별: 5
4
public class StoreActivity extends Activity …. {
private Handler handler = new Handler();
protected void onStart() {
loadingProgress.show();
LoadListThread lThread = new LoadListThread();
lThread.start();
}
private class LoadListThread extends Thread {
public void run() {
URL url = new URL(urlstr);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
...
handler.post(new Runnable() {
public void run() {
loadingProgress.hide();
if (loadingResult) {
localDB.save(loadedData);
drawMarkerForStores(loadedData);
} else {
toasts..short("에러!");
}
}
});
}
}
기능 흐름 제어
데이터 보관 처리
UI 화면 제어
네트
워크
UI 처리 위한 쓰레드
화면 제어
쓰레드 제어
5
public class StoreActivity extends Activity …. {
private MapPoint center;
public void onMapViewDragEnded(
MapView mapView, MapPoint mapPoint) {
center = mapPoint;
loadingProgress.show();
LoadListThread lThread = new LoadListThread();
lThread.start();
}
private class LoadListThread extends Thread {
public void run() {
URL url = new URL(urlstr);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
...
if (center != null) { params.put("center", toCoord(center)); }
...
handler.post(new Runnable() {
public void run() {
loadingProgress.hide();
…
}
});
}
}
사용자 이벤트 처리
UI 의존
데이터
화면 제어 + 쓰레드 제어
6
public class StoreActivity extends Activity …. {
private LocalDB localDB;
public void onMarkerTab(MapView mapView, Marker marker) {
StoreData storeData = localDB.select(marker.getMeta().getId());
if (storeData == null) {
alerts.showAlert("데이터가 없습니다.");
} else {
showBalloon(mapView, storeData);
}
}
private void showBallon(MapView mapView, StoreData storeData) {
BalloonInfoWindow infoWin = new BallonInfoWindow(this,storeData);
mapView.addFigure(infoWin);
…
}
데이터
조회
화면 흐름 제어
위젯
제어
막 만들다 보면
7
UI 조작
흐름 제어
로직
쓰레드
네트워크
DB
도메인
로직
단점
• 실행 흐름 파악이 어렵다.
– 흐름 제어 로직이 산재
• 부분적인 테스트가 어렵다.
– 위젯 조작 + UI 흐름 제어 + 데이터 관리 짬뽕
• 변경이 점점 어려워진다.
– 산재한 로직, 뒤섞인 코드  코드 변경 어려움
8
해결책
9
역할에 따라 알맞게 나누기
10
MVP
Model-View-Presenter
11
모델프리젠터뷰
• 비즈니스 로직과
어플리케이션
데이터
• 어플리케이션의
인터페이스
• 사용자에게는 뷰가 곧
어플리케이션
• 빈번하게 바뀌는 영역
• 모델과 뷰를 연결
• MVP에서 프리젠터는
기능/흐름을 제공
• 요구사항이 프리젠터의
기능에 대응
Model-View-Presenter
12
모델프리젠터뷰
• 비즈니스 로직과
어플리케이션
데이터
• 예, 인증
• 예, 특정 위치 기준
가계 정보
• 이벤트를 프리젠터에
전달
• 예, 로그인 버튼 클릭을
클릭하면 프리젠터에
인증 실행 요청
• 사용자에게 알맞은 화면
제공
• 예, 프리젠터를 통해
전달받은 데이터를
리스트와 같은 위젯을
이용해서 표현
• 로딩 중, 경고 대화창 등
안내
• 사용자 요청에 반응
• 예, 뷰를 통해 인증 요청을
받으면 모델을 사용해서
인증을 수행하고, 결과를
뷰에 전달
• 뷰의 흐름 제어
• 예, 인증 시작 전에 뷰를
통해 진행 중 대화창을
보여주고, 인증에 성공하면
뷰를 통해 메인 화면으로
이동
뷰
• 인터페이스
– 사용자에게 보여질
기능을 정의
– 프리젠터가 호출할 기능
• 예
– 데이터 출력 기능
– 진행 중 알림 기능
• 뷰 구현체
– 인터페이스에 정의한
기능의 구현 제공
– 사용자 이벤트를
프리젠터에 전달
• 예
– 데이터를 리스트로 표시
– 사용자가 항목을
클릭하면 프리젠터에
선택 요청 전달
13
뷰 구현
14
public interface StoreListView {
void showLoadingMessage();
void hideLoadingMessage();
void displayStores(stores);
void showFailMessage();
}
public class MapStoreListView implements StoreListView, … {
private StoreListPresenter presenter;
public void MapStoreListView(StoreListPresenter presenter) {
presenter.setView(this);
}
public void onMapViewDragEnded(
MapView mapView, MapPoint mapPoint) {
Coord center = toCoord(mapView.getCenter()))
presenter.onLocationChange(center);
}
public void showLoadingMessage() {
progress = ProgressDialog.show(this, "", "로딩중");
}
public void hideLoadingMessage() { progress.hide(); }
public void displayStores(List<Store> stores) {
…지도위에 마커 표시
}
프리젠터 정의
• 사용자의 UI 행위를 추상화한 메서드로
기능을 정의
– 뷰 구현에 의존하지 않음
15
onLocationChange: 상점을 조회할 위치 기준을 변경한다는 의미, O
뷰 구현 기술에 종속되지 않음
onMapDragged: 뷰의 지도를 드래그했다는 것을 의미, X
뷰 구현 기술에 종속됨
프리젠터 구현
• 모델과 뷰를 사용해서 사용자의 요청 처리
16
public class StoreListPresenter {
private StoreListView view;
private StoreListModel model;
public void onLocationChange(Coord location) {
view.showLoadingMessage();
try {
List<Store> stores = model.getStoresIn(location, 100);
view.hideLoadingMessage();
view.displayStores(stores);
} catch(Exception e) {
view.hideLoading();
view.showFailMessage();
}
}
UI 로직을
제어
모델로
비즈니스
로직 실행
전형적인 실행 흐름
17
MVP 적용 결과
• 뷰 구현 기술과 UI 로직(프리젠터)의 분리
– UI 로직 응집도 향상
18
MVP 적용 결과
• UI 구현 기술(뷰)과 UI 로직(프리젠터)의 분리
– UI 로직에 영향을 주지 않고 뷰 구현 변경 가능
19
public class MapStoreListView
implements StoreListView, … {
private StoreListPresenter presenter;
…
public void displayStores(List<Store> stores) {
listAdapter.clear();
listAdapter.addAll(stores);
}
public class MapStoreListView
implements StoreListView, … {
private StoreListPresenter presenter;
…
public void displayStores(List<Store> stores) {
map.clearAllMarks();
for(Store store : stores) {
map.addMarker(createMarker(store));
}
}
MVP 적용 결과
• UI 구현 기술(뷰), UI 로직(프리젠터), 도메인
로직(모델) 구현의 분리
– 뷰/모델 구현없이 UI 로직 테스트 가능
• 뷰를 구현하지 않아도 모의(mock) 객체로 UI 로직에
대한 테스트 가능
20
21
안드로이드와 MVP
기본 구조
22
Activity나 Fragment 역할
23
public class MapStoreListActivity implements StoreListView, … {
private StoreListPresenter presenter;
public void onCreate(Bundle savedInstanceState) {
StoreListModel model = new RestStoreListModel();
this.presenter = new StoreListPresenter(this, model);
this.presenter.init();
}
public void onMapViewDragEnded(MapView mapView, MapPoint mapPoint) {
Coord center = toCoord(mapView.getCenter()))
presenter.onLocationChange(center);
}
public void showLoadingMessage() {
progress = ProgressDialog.show(this, "", "로딩중");
}
public void hideLoadingMessage() {
progress.hide();
}
public void displayStores(List<Store> stores) {
…지도위에 마커 표시
}
뷰 구현
프리젠터/모델 객체를
생성하고 연결
안드로이드 앱에서 모델의 특징
• 외부 서버와 통신을 비동기로 처리
– 허니콤(3.0): Main(UI) 쓰레드에서 네트워크 금지
– AsyncTask나 Thread 사용
• 프리젠터에 비동기 결과 전달 방법 필요
– 주요 방법: 콜백(Callback), 옵저버(Observer) 등
24
모델과 콜백
25
public class RestStoreListModel
implements StoreListModel {
public void getStoresIn(Coord center,
int distance,
StoreListCallback callback) {
new Thread(new Runnable() {
public void run() {
try {
… network 처리, 데이터 변환
callback.onSuccess(results);
} catch(Exception ex) {
callback.onFail(ex);
}
}
}).start();
}
public interface StoreListCallback {
void onSuccess(List<Store> stores);
void onFail(Exception ex);
}
프리젠터는 콜백을 통해 결과 수신
26
public class StoreListPresenter {
public void onLocationChange(Coord coord) {
view.showProgressMessage();
model.getStoresIn(coord, 100,
new StoreListCallback() {
public void onSuccess(List<Store> stores) {
view.hideProgressMessage();
view.displayStores(stores);
}
public void onFail(Exception ex) {
view.hideProgressMessage();
view.showFailMessage(ex);
}
});
}
프리젠터와 라이프사이클
• Activity/Fragment의 라이프사이클에 맞춰
기능을 구현해야 할 경우, 프리젠터에
라이프사이클 관련 메서드 정의
27
public class StoreListPresenter {
public void onResume() { … }
public void onStop() { … }
…
}
public class StoreListActivity … {
@Override
protected void onResume() {
super.onResume();
presenter.onResume();
}
@Override
protected void onStop() {
super.onStop();
presenter.onStop();
}
유용한 도구
• Dagger
– 의존 주입(DI)
– Activity에서 직접 프리젠터나 뷰를 생성하지
않도록 해 줌
• RxJava
– 옵저버
– 콜백 인터페이스 대체
28
29
자바스크립트
기본 구현
• 구성 요소는 동일
– 언어 특성상 인터페이스없이 구현
• 초기화
– HTML 로딩 시점에 뷰/모델/프리젠터 초기화
• 예, $.ready()에서 초기화
30
뷰 예시
31
functionMeasureListView(){
varpresenter;
functiononSelect(idx){ presenter.selectMeasure(idx); }
functioninit(){
resizeContent();
...
};
...
init();
return{
setPresenter:function(_presenter){ presenter=_presenter; },
showMeasures:function(measures){
if(measures.length==0){
$("#noData").show();
}else{
$("#hasData").show();
measureBox.setState({measures:measures,loading:false});
}
},
showLoadingError:function(){console.log("error"); }
};
}
프리젠터 예시
32
function MeasureListPresenter(view, model) {
this.reloadList = function() {
model.getMeasureList({
success: function(measures) {
view.showMeasures(measures);
},
error: function() {
view.showLoadingError();
}
});
};
this.selectMeasure = function(idx) {
var measure = model.getMeasure(idx);
view.showMeasure(measure);
};
}
모델 예시
33
functionMeasureListModel(){
varmeasures=[];
functiontoCoord(coordStr){...}
functionconvertToMeasure(feeds){...};
return{
getMeasureList:function(callback){
$.ajax({url:"https://api.mycompany.com/....", type:'GET',
success:function(data){
varmeasures=convertToMeasure(data.feeds);
callback.success(measures);
},
error:function(xhr,status,error){callback.error();}
});
},
getMeasure:function(idx){returnmeasures[idx];}
};
}
초기화 예
34
<script>
$(document).ready(function() {
var model = new MeasureListModel();
var view = new MeasureListView();
var presenter = new MeasureListPresenter(view, model);
view.setPresenter(presenter);
presenter.reloadList();
});
</script>
35
생각할 거리
뷰와 외부 입력
• 뷰의 역할: 외부 데이터 입력
– 기능 예
• 블루투스로 데이터를 받는 기능
• GPS로 현재 좌표 받는 기능
– 이 두 기능은 뷰를 통해 전달받는 사용자 이벤트
36
모델 영역의 구조
• 모델에 얼마나 많은 도메인 로직이 있나?
– 앱/웹에서 모델은 주로 다음의 두 가지 수행
• 서버와 통신
– 중요 로직은 서버에 존재
• 임시로 데이터 보관
– 로컬DB, 메모리 등에 보관
• 모델에 다양한 로직이 있다면 테스트 가능한
구조로 만드는 것이 중요
37
프리젠터
• 인터페이스와 구현체로 구분 필요 여부
– 코드 수준 테스트 대상은 주로 프리젠터와 모델
– 프리젠터가 유연해야 하는 경우 드뭄
– 모델 테스트시 프리젠터에 대한 모의 객체가
필요한 경우 없음
• 프리젠터 메서드 이름, 파라미터, 리턴 타입
– 뷰에 의존하면 안 됨
• 프리젠터 먼저 구현하기
38
39
정리
MVP
• 뷰 구현, UI 로직, 모델 구현을 분리
• 복잡도 감소
– 분리에 따른 복잡도 <<< 뒤섞일 때의 복잡도
• 생산성 향상시키기
– 코드 변경이 상대적으로 쉬워짐
– UI 구현없이 사용자와의 상호작용에 대한 테스트
가능
40
41
끝

More Related Content

What's hot

Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해Nam Hyeonuk
 
실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략YEONG-CHEON YOU
 
인프런 - 스타트업 인프랩 시작 사례
인프런 - 스타트업 인프랩 시작 사례인프런 - 스타트업 인프랩 시작 사례
인프런 - 스타트업 인프랩 시작 사례Hyung Lee
 
オブジェクト指向とSOLID原則の入門
オブジェクト指向とSOLID原則の入門オブジェクト指向とSOLID原則の入門
オブジェクト指向とSOLID原則の入門KISARAGIMakoto
 
LockFree Algorithm
LockFree AlgorithmLockFree Algorithm
LockFree AlgorithmMerry Merry
 
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games ConferenceKGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games ConferenceXionglong Jin
 
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지강 민우
 
리플렉션과 가비지 컬렉션
리플렉션과 가비지 컬렉션리플렉션과 가비지 컬렉션
리플렉션과 가비지 컬렉션QooJuice
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현YEONG-CHEON YOU
 
온라인 게임 처음부터 끝까지 동적언어로 만들기
온라인 게임 처음부터 끝까지 동적언어로 만들기온라인 게임 처음부터 끝까지 동적언어로 만들기
온라인 게임 처음부터 끝까지 동적언어로 만들기Seungjae Lee
 
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012devCAT Studio, NEXON
 
스마트폰 온라인 게임에서 고려해야 할 것들
스마트폰 온라인 게임에서 고려해야 할 것들스마트폰 온라인 게임에서 고려해야 할 것들
스마트폰 온라인 게임에서 고려해야 할 것들Hyunjik Bae
 
임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012devCAT Studio, NEXON
 
나만의 엔진 개발하기
나만의 엔진 개발하기나만의 엔진 개발하기
나만의 엔진 개발하기YEONG-CHEON YOU
 
송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010devCAT Studio, NEXON
 
중앙 서버 없는 게임 로직
중앙 서버 없는 게임 로직중앙 서버 없는 게임 로직
중앙 서버 없는 게임 로직Hoyoung Choi
 
Node.js Express
Node.js  ExpressNode.js  Express
Node.js ExpressEyal Vardi
 
モダン PHP テクニック 12 選 ―PsalmとPHP 8.1で今はこんなこともできる!―
モダン PHP テクニック 12 選 ―PsalmとPHP 8.1で今はこんなこともできる!―モダン PHP テクニック 12 選 ―PsalmとPHP 8.1で今はこんなこともできる!―
モダン PHP テクニック 12 選 ―PsalmとPHP 8.1で今はこんなこともできる!―shinjiigarashi
 

What's hot (20)

Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해
 
실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략
 
인프런 - 스타트업 인프랩 시작 사례
인프런 - 스타트업 인프랩 시작 사례인프런 - 스타트업 인프랩 시작 사례
인프런 - 스타트업 인프랩 시작 사례
 
Iocp advanced
Iocp advancedIocp advanced
Iocp advanced
 
オブジェクト指向とSOLID原則の入門
オブジェクト指向とSOLID原則の入門オブジェクト指向とSOLID原則の入門
オブジェクト指向とSOLID原則の入門
 
LockFree Algorithm
LockFree AlgorithmLockFree Algorithm
LockFree Algorithm
 
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games ConferenceKGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
 
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
 
리플렉션과 가비지 컬렉션
리플렉션과 가비지 컬렉션리플렉션과 가비지 컬렉션
리플렉션과 가비지 컬렉션
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현
 
온라인 게임 처음부터 끝까지 동적언어로 만들기
온라인 게임 처음부터 끝까지 동적언어로 만들기온라인 게임 처음부터 끝까지 동적언어로 만들기
온라인 게임 처음부터 끝까지 동적언어로 만들기
 
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
 
Angular 2 observables
Angular 2 observablesAngular 2 observables
Angular 2 observables
 
스마트폰 온라인 게임에서 고려해야 할 것들
스마트폰 온라인 게임에서 고려해야 할 것들스마트폰 온라인 게임에서 고려해야 할 것들
스마트폰 온라인 게임에서 고려해야 할 것들
 
임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012
 
나만의 엔진 개발하기
나만의 엔진 개발하기나만의 엔진 개발하기
나만의 엔진 개발하기
 
송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010
 
중앙 서버 없는 게임 로직
중앙 서버 없는 게임 로직중앙 서버 없는 게임 로직
중앙 서버 없는 게임 로직
 
Node.js Express
Node.js  ExpressNode.js  Express
Node.js Express
 
モダン PHP テクニック 12 選 ―PsalmとPHP 8.1で今はこんなこともできる!―
モダン PHP テクニック 12 選 ―PsalmとPHP 8.1で今はこんなこともできる!―モダン PHP テクニック 12 選 ―PsalmとPHP 8.1で今はこんなこともできる!―
モダン PHP テクニック 12 選 ―PsalmとPHP 8.1で今はこんなこともできる!―
 

Viewers also liked

객체 지향 발담그기 JCO 컨퍼런스 14회
객체 지향 발담그기 JCO 컨퍼런스 14회객체 지향 발담그기 JCO 컨퍼런스 14회
객체 지향 발담그기 JCO 컨퍼런스 14회beom kyun choi
 
Ddd start 부록 지앤선&ksug
Ddd start 부록 지앤선&ksugDdd start 부록 지앤선&ksug
Ddd start 부록 지앤선&ksugbeom kyun choi
 
모델링 연습 리뷰
모델링 연습 리뷰모델링 연습 리뷰
모델링 연습 리뷰beom kyun choi
 
도메인구현 KSUG 20151128
도메인구현 KSUG 20151128도메인구현 KSUG 20151128
도메인구현 KSUG 20151128beom kyun choi
 
주니어 개발자도 이해 할 수 있는 아름다운 JVM 세상
주니어 개발자도 이해 할 수 있는 아름다운 JVM 세상주니어 개발자도 이해 할 수 있는 아름다운 JVM 세상
주니어 개발자도 이해 할 수 있는 아름다운 JVM 세상Darion Kim
 
[JWPA-1]의존성 주입(Dependency injection)
[JWPA-1]의존성 주입(Dependency injection)[JWPA-1]의존성 주입(Dependency injection)
[JWPA-1]의존성 주입(Dependency injection)Young-Ho Cho
 
토이 프로젝트를 하자.Pptx
토이 프로젝트를 하자.Pptx토이 프로젝트를 하자.Pptx
토이 프로젝트를 하자.PptxMyeongin Woo
 
주니어 개발자도 이해 할 수 있는 의존성 주입(Dependency Injection)
주니어 개발자도 이해 할 수 있는 의존성 주입(Dependency Injection)주니어 개발자도 이해 할 수 있는 의존성 주입(Dependency Injection)
주니어 개발자도 이해 할 수 있는 의존성 주입(Dependency Injection)Darion Kim
 
Dagger 2.0 을 활용한 의존성 주입
Dagger 2.0 을 활용한 의존성 주입Dagger 2.0 을 활용한 의존성 주입
Dagger 2.0 을 활용한 의존성 주입승용 윤
 

Viewers also liked (10)

객체 지향 발담그기 JCO 컨퍼런스 14회
객체 지향 발담그기 JCO 컨퍼런스 14회객체 지향 발담그기 JCO 컨퍼런스 14회
객체 지향 발담그기 JCO 컨퍼런스 14회
 
Ddd start 부록 지앤선&ksug
Ddd start 부록 지앤선&ksugDdd start 부록 지앤선&ksug
Ddd start 부록 지앤선&ksug
 
모델링 연습 리뷰
모델링 연습 리뷰모델링 연습 리뷰
모델링 연습 리뷰
 
도메인구현 KSUG 20151128
도메인구현 KSUG 20151128도메인구현 KSUG 20151128
도메인구현 KSUG 20151128
 
주니어 개발자도 이해 할 수 있는 아름다운 JVM 세상
주니어 개발자도 이해 할 수 있는 아름다운 JVM 세상주니어 개발자도 이해 할 수 있는 아름다운 JVM 세상
주니어 개발자도 이해 할 수 있는 아름다운 JVM 세상
 
[JWPA-1]의존성 주입(Dependency injection)
[JWPA-1]의존성 주입(Dependency injection)[JWPA-1]의존성 주입(Dependency injection)
[JWPA-1]의존성 주입(Dependency injection)
 
토이 프로젝트를 하자.Pptx
토이 프로젝트를 하자.Pptx토이 프로젝트를 하자.Pptx
토이 프로젝트를 하자.Pptx
 
주니어 개발자도 이해 할 수 있는 의존성 주입(Dependency Injection)
주니어 개발자도 이해 할 수 있는 의존성 주입(Dependency Injection)주니어 개발자도 이해 할 수 있는 의존성 주입(Dependency Injection)
주니어 개발자도 이해 할 수 있는 의존성 주입(Dependency Injection)
 
Kotlin.md
Kotlin.mdKotlin.md
Kotlin.md
 
Dagger 2.0 을 활용한 의존성 주입
Dagger 2.0 을 활용한 의존성 주입Dagger 2.0 을 활용한 의존성 주입
Dagger 2.0 을 활용한 의존성 주입
 

Similar to MVP 패턴 소개

Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)beom kyun choi
 
MVVM Pattern for Android
MVVM Pattern for AndroidMVVM Pattern for Android
MVVM Pattern for Androidtaeinkim6
 
자바스크립트 프레임워크 살펴보기
자바스크립트 프레임워크 살펴보기자바스크립트 프레임워크 살펴보기
자바스크립트 프레임워크 살펴보기Jeado Ko
 
Design pattern 옵저버
Design pattern 옵저버Design pattern 옵저버
Design pattern 옵저버Sukjin Yun
 
CRUD Pattern in Ajax
CRUD Pattern in AjaxCRUD Pattern in Ajax
CRUD Pattern in AjaxRhio Kim
 
Create App Easier With SVC Pattern - DroidKnights 2019 @Seoul
Create App Easier With SVC Pattern - DroidKnights 2019 @SeoulCreate App Easier With SVC Pattern - DroidKnights 2019 @Seoul
Create App Easier With SVC Pattern - DroidKnights 2019 @SeoulBansook Nam
 
C++ 개발자와 함께 하는 visual studio 2013
C++ 개발자와 함께 하는 visual studio 2013C++ 개발자와 함께 하는 visual studio 2013
C++ 개발자와 함께 하는 visual studio 2013명신 김
 
#19.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#19.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...#19.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#19.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...탑크리에듀(구로디지털단지역3번출구 2분거리)
 
주니어 입장에서 바라보는 디자인패턴 & 아키텍쳐.pdf
주니어 입장에서 바라보는 디자인패턴 & 아키텍쳐.pdf주니어 입장에서 바라보는 디자인패턴 & 아키텍쳐.pdf
주니어 입장에서 바라보는 디자인패턴 & 아키텍쳐.pdf병근 손
 
Domain Specific Languages With Groovy
Domain Specific Languages With GroovyDomain Specific Languages With Groovy
Domain Specific Languages With GroovyTommy C. Kang
 
[D2 오픈세미나]3.web view hybridapp
[D2 오픈세미나]3.web view hybridapp[D2 오픈세미나]3.web view hybridapp
[D2 오픈세미나]3.web view hybridappNAVER D2
 
자바스크립트의 또다른 발전, Backbone.js
자바스크립트의 또다른 발전, Backbone.js자바스크립트의 또다른 발전, Backbone.js
자바스크립트의 또다른 발전, Backbone.jsJinKwon Lee
 
Facebook은 React를 왜 만들었을까?
Facebook은 React를 왜 만들었을까? Facebook은 React를 왜 만들었을까?
Facebook은 React를 왜 만들었을까? Kim Hunmin
 
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기현철 조
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Ryan Park
 
[TECHCON 2019: MOBILE - Android]2.예제에서는 알려주지 않는 Model 이야기
[TECHCON 2019: MOBILE - Android]2.예제에서는 알려주지 않는 Model 이야기[TECHCON 2019: MOBILE - Android]2.예제에서는 알려주지 않는 Model 이야기
[TECHCON 2019: MOBILE - Android]2.예제에서는 알려주지 않는 Model 이야기NAVER Engineering
 
2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축
2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축
2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축Youngil Cho
 

Similar to MVP 패턴 소개 (20)

Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)
 
MVVM Pattern for Android
MVVM Pattern for AndroidMVVM Pattern for Android
MVVM Pattern for Android
 
자바스크립트 프레임워크 살펴보기
자바스크립트 프레임워크 살펴보기자바스크립트 프레임워크 살펴보기
자바스크립트 프레임워크 살펴보기
 
Design pattern 옵저버
Design pattern 옵저버Design pattern 옵저버
Design pattern 옵저버
 
CRUD Pattern in Ajax
CRUD Pattern in AjaxCRUD Pattern in Ajax
CRUD Pattern in Ajax
 
Create App Easier With SVC Pattern - DroidKnights 2019 @Seoul
Create App Easier With SVC Pattern - DroidKnights 2019 @SeoulCreate App Easier With SVC Pattern - DroidKnights 2019 @Seoul
Create App Easier With SVC Pattern - DroidKnights 2019 @Seoul
 
C++ 개발자와 함께 하는 visual studio 2013
C++ 개발자와 함께 하는 visual studio 2013C++ 개발자와 함께 하는 visual studio 2013
C++ 개발자와 함께 하는 visual studio 2013
 
#19.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#19.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...#19.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#19.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
 
주니어 입장에서 바라보는 디자인패턴 & 아키텍쳐.pdf
주니어 입장에서 바라보는 디자인패턴 & 아키텍쳐.pdf주니어 입장에서 바라보는 디자인패턴 & 아키텍쳐.pdf
주니어 입장에서 바라보는 디자인패턴 & 아키텍쳐.pdf
 
Coded ui가이드
Coded ui가이드Coded ui가이드
Coded ui가이드
 
Domain Specific Languages With Groovy
Domain Specific Languages With GroovyDomain Specific Languages With Groovy
Domain Specific Languages With Groovy
 
react-ko.pdf
react-ko.pdfreact-ko.pdf
react-ko.pdf
 
[D2 오픈세미나]3.web view hybridapp
[D2 오픈세미나]3.web view hybridapp[D2 오픈세미나]3.web view hybridapp
[D2 오픈세미나]3.web view hybridapp
 
Eclipse RCP 1/2
Eclipse RCP 1/2Eclipse RCP 1/2
Eclipse RCP 1/2
 
자바스크립트의 또다른 발전, Backbone.js
자바스크립트의 또다른 발전, Backbone.js자바스크립트의 또다른 발전, Backbone.js
자바스크립트의 또다른 발전, Backbone.js
 
Facebook은 React를 왜 만들었을까?
Facebook은 React를 왜 만들었을까? Facebook은 React를 왜 만들었을까?
Facebook은 React를 왜 만들었을까?
 
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005
 
[TECHCON 2019: MOBILE - Android]2.예제에서는 알려주지 않는 Model 이야기
[TECHCON 2019: MOBILE - Android]2.예제에서는 알려주지 않는 Model 이야기[TECHCON 2019: MOBILE - Android]2.예제에서는 알려주지 않는 Model 이야기
[TECHCON 2019: MOBILE - Android]2.예제에서는 알려주지 않는 Model 이야기
 
2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축
2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축
2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축
 

More from beom kyun choi

옛날 웹 개발자가 잠깐 맛본 Vue.js 소개
옛날 웹 개발자가 잠깐 맛본 Vue.js 소개옛날 웹 개발자가 잠깐 맛본 Vue.js 소개
옛날 웹 개발자가 잠깐 맛본 Vue.js 소개beom kyun choi
 
DDD로 복잡함 다루기
DDD로 복잡함 다루기DDD로 복잡함 다루기
DDD로 복잡함 다루기beom kyun choi
 
TDD 발담그기 @ 공감세미나
TDD 발담그기 @ 공감세미나TDD 발담그기 @ 공감세미나
TDD 발담그기 @ 공감세미나beom kyun choi
 
keras 빨리 훑어보기(intro)
keras 빨리 훑어보기(intro)keras 빨리 훑어보기(intro)
keras 빨리 훑어보기(intro)beom kyun choi
 
Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀beom kyun choi
 
파이썬 언어 기초
파이썬 언어 기초파이썬 언어 기초
파이썬 언어 기초beom kyun choi
 
Event source 학습 내용 공유
Event source 학습 내용 공유Event source 학습 내용 공유
Event source 학습 내용 공유beom kyun choi
 
ALS WS에 대한 이해 자료
ALS WS에 대한 이해 자료ALS WS에 대한 이해 자료
ALS WS에 대한 이해 자료beom kyun choi
 
리뷰의 기술 소개
리뷰의 기술 소개리뷰의 기술 소개
리뷰의 기술 소개beom kyun choi
 
스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해beom kyun choi
 
자바8 스트림 API 소개
자바8 스트림 API 소개자바8 스트림 API 소개
자바8 스트림 API 소개beom kyun choi
 
자바8 람다식 소개
자바8 람다식 소개자바8 람다식 소개
자바8 람다식 소개beom kyun choi
 
하둡2 YARN 짧게 보기
하둡2 YARN 짧게 보기하둡2 YARN 짧게 보기
하둡2 YARN 짧게 보기beom kyun choi
 
차원축소 훑어보기 (PCA, SVD, NMF)
차원축소 훑어보기 (PCA, SVD, NMF)차원축소 훑어보기 (PCA, SVD, NMF)
차원축소 훑어보기 (PCA, SVD, NMF)beom kyun choi
 
Hive 입문 발표 자료
Hive 입문 발표 자료Hive 입문 발표 자료
Hive 입문 발표 자료beom kyun choi
 

More from beom kyun choi (20)

옛날 웹 개발자가 잠깐 맛본 Vue.js 소개
옛날 웹 개발자가 잠깐 맛본 Vue.js 소개옛날 웹 개발자가 잠깐 맛본 Vue.js 소개
옛날 웹 개발자가 잠깐 맛본 Vue.js 소개
 
DDD로 복잡함 다루기
DDD로 복잡함 다루기DDD로 복잡함 다루기
DDD로 복잡함 다루기
 
TDD 발담그기 @ 공감세미나
TDD 발담그기 @ 공감세미나TDD 발담그기 @ 공감세미나
TDD 발담그기 @ 공감세미나
 
keras 빨리 훑어보기(intro)
keras 빨리 훑어보기(intro)keras 빨리 훑어보기(intro)
keras 빨리 훑어보기(intro)
 
DDD 준비 서문래
DDD 준비 서문래DDD 준비 서문래
DDD 준비 서문래
 
Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀
 
파이썬 언어 기초
파이썬 언어 기초파이썬 언어 기초
파이썬 언어 기초
 
Event source 학습 내용 공유
Event source 학습 내용 공유Event source 학습 내용 공유
Event source 학습 내용 공유
 
Spring Boot 소개
Spring Boot 소개Spring Boot 소개
Spring Boot 소개
 
ALS WS에 대한 이해 자료
ALS WS에 대한 이해 자료ALS WS에 대한 이해 자료
ALS WS에 대한 이해 자료
 
리뷰의 기술 소개
리뷰의 기술 소개리뷰의 기술 소개
리뷰의 기술 소개
 
스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해
 
자바8 스트림 API 소개
자바8 스트림 API 소개자바8 스트림 API 소개
자바8 스트림 API 소개
 
자바8 람다식 소개
자바8 람다식 소개자바8 람다식 소개
자바8 람다식 소개
 
Zookeeper 소개
Zookeeper 소개Zookeeper 소개
Zookeeper 소개
 
하둡2 YARN 짧게 보기
하둡2 YARN 짧게 보기하둡2 YARN 짧게 보기
하둡2 YARN 짧게 보기
 
차원축소 훑어보기 (PCA, SVD, NMF)
차원축소 훑어보기 (PCA, SVD, NMF)차원축소 훑어보기 (PCA, SVD, NMF)
차원축소 훑어보기 (PCA, SVD, NMF)
 
Storm 훑어보기
Storm 훑어보기Storm 훑어보기
Storm 훑어보기
 
Hive 입문 발표 자료
Hive 입문 발표 자료Hive 입문 발표 자료
Hive 입문 발표 자료
 
HBase 훑어보기
HBase 훑어보기HBase 훑어보기
HBase 훑어보기
 

MVP 패턴 소개

  • 1. MVP 패턴 소개 (안드로이드) 신림프로그래머, 최범균, 2016-06-18 madvirus@madvirus.net
  • 2. 다룰 내용 • 막 만들면 • MVP 패턴 – 적용 결과 • MVP 패턴 적용 예 – 안드로이드 – 자바스크립트 • 정리 2
  • 3. 간단한 앱, 막 만들면… 3 드래그 탭 미림분식 별: 5
  • 4. 4 public class StoreActivity extends Activity …. { private Handler handler = new Handler(); protected void onStart() { loadingProgress.show(); LoadListThread lThread = new LoadListThread(); lThread.start(); } private class LoadListThread extends Thread { public void run() { URL url = new URL(urlstr); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); ... handler.post(new Runnable() { public void run() { loadingProgress.hide(); if (loadingResult) { localDB.save(loadedData); drawMarkerForStores(loadedData); } else { toasts..short("에러!"); } } }); } } 기능 흐름 제어 데이터 보관 처리 UI 화면 제어 네트 워크 UI 처리 위한 쓰레드 화면 제어 쓰레드 제어
  • 5. 5 public class StoreActivity extends Activity …. { private MapPoint center; public void onMapViewDragEnded( MapView mapView, MapPoint mapPoint) { center = mapPoint; loadingProgress.show(); LoadListThread lThread = new LoadListThread(); lThread.start(); } private class LoadListThread extends Thread { public void run() { URL url = new URL(urlstr); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); ... if (center != null) { params.put("center", toCoord(center)); } ... handler.post(new Runnable() { public void run() { loadingProgress.hide(); … } }); } } 사용자 이벤트 처리 UI 의존 데이터 화면 제어 + 쓰레드 제어
  • 6. 6 public class StoreActivity extends Activity …. { private LocalDB localDB; public void onMarkerTab(MapView mapView, Marker marker) { StoreData storeData = localDB.select(marker.getMeta().getId()); if (storeData == null) { alerts.showAlert("데이터가 없습니다."); } else { showBalloon(mapView, storeData); } } private void showBallon(MapView mapView, StoreData storeData) { BalloonInfoWindow infoWin = new BallonInfoWindow(this,storeData); mapView.addFigure(infoWin); … } 데이터 조회 화면 흐름 제어 위젯 제어
  • 7. 막 만들다 보면 7 UI 조작 흐름 제어 로직 쓰레드 네트워크 DB 도메인 로직
  • 8. 단점 • 실행 흐름 파악이 어렵다. – 흐름 제어 로직이 산재 • 부분적인 테스트가 어렵다. – 위젯 조작 + UI 흐름 제어 + 데이터 관리 짬뽕 • 변경이 점점 어려워진다. – 산재한 로직, 뒤섞인 코드  코드 변경 어려움 8
  • 11. Model-View-Presenter 11 모델프리젠터뷰 • 비즈니스 로직과 어플리케이션 데이터 • 어플리케이션의 인터페이스 • 사용자에게는 뷰가 곧 어플리케이션 • 빈번하게 바뀌는 영역 • 모델과 뷰를 연결 • MVP에서 프리젠터는 기능/흐름을 제공 • 요구사항이 프리젠터의 기능에 대응
  • 12. Model-View-Presenter 12 모델프리젠터뷰 • 비즈니스 로직과 어플리케이션 데이터 • 예, 인증 • 예, 특정 위치 기준 가계 정보 • 이벤트를 프리젠터에 전달 • 예, 로그인 버튼 클릭을 클릭하면 프리젠터에 인증 실행 요청 • 사용자에게 알맞은 화면 제공 • 예, 프리젠터를 통해 전달받은 데이터를 리스트와 같은 위젯을 이용해서 표현 • 로딩 중, 경고 대화창 등 안내 • 사용자 요청에 반응 • 예, 뷰를 통해 인증 요청을 받으면 모델을 사용해서 인증을 수행하고, 결과를 뷰에 전달 • 뷰의 흐름 제어 • 예, 인증 시작 전에 뷰를 통해 진행 중 대화창을 보여주고, 인증에 성공하면 뷰를 통해 메인 화면으로 이동
  • 13. 뷰 • 인터페이스 – 사용자에게 보여질 기능을 정의 – 프리젠터가 호출할 기능 • 예 – 데이터 출력 기능 – 진행 중 알림 기능 • 뷰 구현체 – 인터페이스에 정의한 기능의 구현 제공 – 사용자 이벤트를 프리젠터에 전달 • 예 – 데이터를 리스트로 표시 – 사용자가 항목을 클릭하면 프리젠터에 선택 요청 전달 13
  • 14. 뷰 구현 14 public interface StoreListView { void showLoadingMessage(); void hideLoadingMessage(); void displayStores(stores); void showFailMessage(); } public class MapStoreListView implements StoreListView, … { private StoreListPresenter presenter; public void MapStoreListView(StoreListPresenter presenter) { presenter.setView(this); } public void onMapViewDragEnded( MapView mapView, MapPoint mapPoint) { Coord center = toCoord(mapView.getCenter())) presenter.onLocationChange(center); } public void showLoadingMessage() { progress = ProgressDialog.show(this, "", "로딩중"); } public void hideLoadingMessage() { progress.hide(); } public void displayStores(List<Store> stores) { …지도위에 마커 표시 }
  • 15. 프리젠터 정의 • 사용자의 UI 행위를 추상화한 메서드로 기능을 정의 – 뷰 구현에 의존하지 않음 15 onLocationChange: 상점을 조회할 위치 기준을 변경한다는 의미, O 뷰 구현 기술에 종속되지 않음 onMapDragged: 뷰의 지도를 드래그했다는 것을 의미, X 뷰 구현 기술에 종속됨
  • 16. 프리젠터 구현 • 모델과 뷰를 사용해서 사용자의 요청 처리 16 public class StoreListPresenter { private StoreListView view; private StoreListModel model; public void onLocationChange(Coord location) { view.showLoadingMessage(); try { List<Store> stores = model.getStoresIn(location, 100); view.hideLoadingMessage(); view.displayStores(stores); } catch(Exception e) { view.hideLoading(); view.showFailMessage(); } } UI 로직을 제어 모델로 비즈니스 로직 실행
  • 18. MVP 적용 결과 • 뷰 구현 기술과 UI 로직(프리젠터)의 분리 – UI 로직 응집도 향상 18
  • 19. MVP 적용 결과 • UI 구현 기술(뷰)과 UI 로직(프리젠터)의 분리 – UI 로직에 영향을 주지 않고 뷰 구현 변경 가능 19 public class MapStoreListView implements StoreListView, … { private StoreListPresenter presenter; … public void displayStores(List<Store> stores) { listAdapter.clear(); listAdapter.addAll(stores); } public class MapStoreListView implements StoreListView, … { private StoreListPresenter presenter; … public void displayStores(List<Store> stores) { map.clearAllMarks(); for(Store store : stores) { map.addMarker(createMarker(store)); } }
  • 20. MVP 적용 결과 • UI 구현 기술(뷰), UI 로직(프리젠터), 도메인 로직(모델) 구현의 분리 – 뷰/모델 구현없이 UI 로직 테스트 가능 • 뷰를 구현하지 않아도 모의(mock) 객체로 UI 로직에 대한 테스트 가능 20
  • 23. Activity나 Fragment 역할 23 public class MapStoreListActivity implements StoreListView, … { private StoreListPresenter presenter; public void onCreate(Bundle savedInstanceState) { StoreListModel model = new RestStoreListModel(); this.presenter = new StoreListPresenter(this, model); this.presenter.init(); } public void onMapViewDragEnded(MapView mapView, MapPoint mapPoint) { Coord center = toCoord(mapView.getCenter())) presenter.onLocationChange(center); } public void showLoadingMessage() { progress = ProgressDialog.show(this, "", "로딩중"); } public void hideLoadingMessage() { progress.hide(); } public void displayStores(List<Store> stores) { …지도위에 마커 표시 } 뷰 구현 프리젠터/모델 객체를 생성하고 연결
  • 24. 안드로이드 앱에서 모델의 특징 • 외부 서버와 통신을 비동기로 처리 – 허니콤(3.0): Main(UI) 쓰레드에서 네트워크 금지 – AsyncTask나 Thread 사용 • 프리젠터에 비동기 결과 전달 방법 필요 – 주요 방법: 콜백(Callback), 옵저버(Observer) 등 24
  • 25. 모델과 콜백 25 public class RestStoreListModel implements StoreListModel { public void getStoresIn(Coord center, int distance, StoreListCallback callback) { new Thread(new Runnable() { public void run() { try { … network 처리, 데이터 변환 callback.onSuccess(results); } catch(Exception ex) { callback.onFail(ex); } } }).start(); } public interface StoreListCallback { void onSuccess(List<Store> stores); void onFail(Exception ex); }
  • 26. 프리젠터는 콜백을 통해 결과 수신 26 public class StoreListPresenter { public void onLocationChange(Coord coord) { view.showProgressMessage(); model.getStoresIn(coord, 100, new StoreListCallback() { public void onSuccess(List<Store> stores) { view.hideProgressMessage(); view.displayStores(stores); } public void onFail(Exception ex) { view.hideProgressMessage(); view.showFailMessage(ex); } }); }
  • 27. 프리젠터와 라이프사이클 • Activity/Fragment의 라이프사이클에 맞춰 기능을 구현해야 할 경우, 프리젠터에 라이프사이클 관련 메서드 정의 27 public class StoreListPresenter { public void onResume() { … } public void onStop() { … } … } public class StoreListActivity … { @Override protected void onResume() { super.onResume(); presenter.onResume(); } @Override protected void onStop() { super.onStop(); presenter.onStop(); }
  • 28. 유용한 도구 • Dagger – 의존 주입(DI) – Activity에서 직접 프리젠터나 뷰를 생성하지 않도록 해 줌 • RxJava – 옵저버 – 콜백 인터페이스 대체 28
  • 30. 기본 구현 • 구성 요소는 동일 – 언어 특성상 인터페이스없이 구현 • 초기화 – HTML 로딩 시점에 뷰/모델/프리젠터 초기화 • 예, $.ready()에서 초기화 30
  • 31. 뷰 예시 31 functionMeasureListView(){ varpresenter; functiononSelect(idx){ presenter.selectMeasure(idx); } functioninit(){ resizeContent(); ... }; ... init(); return{ setPresenter:function(_presenter){ presenter=_presenter; }, showMeasures:function(measures){ if(measures.length==0){ $("#noData").show(); }else{ $("#hasData").show(); measureBox.setState({measures:measures,loading:false}); } }, showLoadingError:function(){console.log("error"); } }; }
  • 32. 프리젠터 예시 32 function MeasureListPresenter(view, model) { this.reloadList = function() { model.getMeasureList({ success: function(measures) { view.showMeasures(measures); }, error: function() { view.showLoadingError(); } }); }; this.selectMeasure = function(idx) { var measure = model.getMeasure(idx); view.showMeasure(measure); }; }
  • 34. 초기화 예 34 <script> $(document).ready(function() { var model = new MeasureListModel(); var view = new MeasureListView(); var presenter = new MeasureListPresenter(view, model); view.setPresenter(presenter); presenter.reloadList(); }); </script>
  • 36. 뷰와 외부 입력 • 뷰의 역할: 외부 데이터 입력 – 기능 예 • 블루투스로 데이터를 받는 기능 • GPS로 현재 좌표 받는 기능 – 이 두 기능은 뷰를 통해 전달받는 사용자 이벤트 36
  • 37. 모델 영역의 구조 • 모델에 얼마나 많은 도메인 로직이 있나? – 앱/웹에서 모델은 주로 다음의 두 가지 수행 • 서버와 통신 – 중요 로직은 서버에 존재 • 임시로 데이터 보관 – 로컬DB, 메모리 등에 보관 • 모델에 다양한 로직이 있다면 테스트 가능한 구조로 만드는 것이 중요 37
  • 38. 프리젠터 • 인터페이스와 구현체로 구분 필요 여부 – 코드 수준 테스트 대상은 주로 프리젠터와 모델 – 프리젠터가 유연해야 하는 경우 드뭄 – 모델 테스트시 프리젠터에 대한 모의 객체가 필요한 경우 없음 • 프리젠터 메서드 이름, 파라미터, 리턴 타입 – 뷰에 의존하면 안 됨 • 프리젠터 먼저 구현하기 38
  • 40. MVP • 뷰 구현, UI 로직, 모델 구현을 분리 • 복잡도 감소 – 분리에 따른 복잡도 <<< 뒤섞일 때의 복잡도 • 생산성 향상시키기 – 코드 변경이 상대적으로 쉬워짐 – UI 구현없이 사용자와의 상호작용에 대한 테스트 가능 40