Altruistic Programmer's Blog (KR)

이타주의 프로그래머의 블로그

Archive for May, 2009

MVC vs MVP (2)

without comments

[옛날 블로그 글입니다. 2009.05.30]

저번에 구글 테스팅 블로그의 아티클을 소개하는 MVC vs MVP라는 글을 썼는데요. 구글에서 소개하는 MVC와 MVP의 구분이 생각하던거랑 다르기도 하고, 사실 저도 잘 모르겠고 해서 공부를 해봤습니다. 아주 재미있는 공부였구요, 간단한 정리와 참고 자료를 공유하겠습니다.

아, 마틴 파울러 아저씨의 말이 참 공감이 가는데요. 아키텍쳐를 이해하는 것은 어렵다는 점입니다. 이 글도 대략의 이해를 위한 글 정도로 읽어주세요 ^^

MVC

UI 관련 패턴으로서 가장 많이 언급되면서도, 가장 많이 오용되는 용어라고 합니다. 우선 역할 정리부터.

Model : 도메인 데이타 및 관련 로직.
View : 도메인 데이타를 화면에 표시하는 담당. UI 컨트롤 및 UI 로직. Model에 직접 접근.
Controller : 사용자의 IO 입력 (마우스/키보드)을 처리하는 담당. Model에 직접 접근.

Smalltalk-80에서 처음 등장했는데요, 이 당시는 화면 표시와 사용자의 입력 처리가 별개의 일이였다고 합니다. MS Windows가 나오면서 UI Control(Widget)이 화면 표시와 사용자 입력 처리를 동시에 해버려서, 원조 MVC를 적용하기 어려워 졌답니다. 그러니 요즘의 프로그래밍 환경에서 MVC를 사용한다는 건 좀 안맞는 말이죠.

우선 MVP를 보고 더 얘기해보죠.

MVP

MVP의 원조격인 Taligent MVP는 지금의 모습보다 많이 복잡하더군요. 어쨌든 MVP 패턴이 가장 대중화 된 것은 돌고래 스몰토크에서 구현한 MVP랍니다. 역할을 보면.

Model : 도메인 데이타 및 관련 로직.
View : 도메인 데이타를 화면에 표시하는 담당. UI 컨트롤 및 UI 로직.
           사용자의 입력을 Presenter로 위임.
           모델에 직접 접근할 수도 있음.
Presenter : Model과 View 사이의 중재자. 복잡한 UI 로직. 모델에 직접 접근.

MVC에 비해서 View의 역할이 대폭 줄어드는데, View의 구현방식에 따라 역할의 범위가 달라질 수 있습니다. 최소의 경우라면 Model에 대한 접근을 전혀 하지 않고, 유저의 입력은 바로 Presenter에게 넘겨주기만 합니다. 그리고 Model의 변경사항을 View에 적용하는 것도 Presenter가 모두 합니다. 이것이 마틴 파울러의 Passive View 패턴이랍니다.

반면에 View가 Model의 변경사항을 스스로 적용하는 경우도 있는데, 이것이 마틴 파울러의 Supervising Controller 패턴이랍니다.

하지만 중요한 것은 패턴의 이름이 아니라, 구현방식에 따라서 역할이 조금씩 변할 수 있다는 점이겠죠.

MVC vs MVP

놀라운 사실 한가지는 MVC  패턴이 자주 오해되고 있다는 점입니다. 예를 들어, 돌고래 스몰토크에서 언급되는 MVC는 Smalltalk-80의 MVC가 아니라 VisualWorks의 MVC를 말하는 것인데, VisualWorks에는 Application Model( Presentation Model과 유사 )이라는 개념이 있어서 Model을 감싸는 또 하나의 Model이 있습니다. 원조 MVC와는 좀 다르죠.

Smalltalk-80의 MVC를 기준으로 본다면 크게 '화면 표시와 입력 처리의 분리', 'Observer 패턴을 통한 UI 처리와 도메인 모델의 분리'가 가장 큰 특징이라 할 수 있겠습니다.

돌고래 스몰토크의 MVP를 기준으로 본다면 'Model과 View를 중계하는 Presenter', 'Observer 패턴을 통한 UI 처리와 도메인 모델의 분리' 가 큰 특징이라 할 수 있습니다.

Passive View 패턴의 MVP라면 View가 아무런 로직도 갖지 않고 모든 것을 Presenter에 위임하는데요 테스트의 편의성을 위해 발전된 것이라고 합니다. Presenter를 테스트 하는 것 만으로 충분히 테스트가 되니까요. 구글 테스팅 블로그의 아티클에서 MVP 사용을 권장하는 것도 같은 맥락입니다.

다만 구글 테스팅 블로그의 아티클에 나오는 그림에는 일부 논쟁의 여지가 있기는 합니다. 아티클에 나오는 MVC 그림은 사실 Supervising Controller 패턴의 MVP를 닮았구요,  MVP 그림은 Passive View 패턴의 MVP의 모습입니다. 하지만 MVC 그림의 경우에는 저도 그다지 어색하지 않았는데요, 그런 식으로 왜곡되어서 널리 퍼져있는 것 같습니다.

관련 패턴

이번에 MVC와 MVP를 공부하면서 좋았던 점은 관련된 패턴들을 더 알게되었다는 건데요. 지면상(?) 간단히만 소개드리겠습니다.

Application Model( Presentation Model ) : 앞에 한 번 나왔죠. 예를 들어서 말이죠, 리스트 박스의 현재 선택된 아이템의 인덱스는 어디에 보관되야 맞을까요? Model? View?

이런 문제를 해결하기 위해 Model을 래핑하는 Model이 등장했습니다. 이 Model은 UI에 대한 정보도 좀 알고 있기 때문에 Application Model 혹은 Presentation Model이라고 불리는데 조금은 차이가 있답니다.

Hierarchical MVC : MVC가 계층적인 구조를 이루는 것인데요. 일반적인 UI이라면 보통은 계층 구조를 이루게 되죠. 제가 저번 글에서 애플의 코코아가 MVC(MVP)를 잘 쓰는 것 같다고 했는데요, 바로 이 Hierarchical MVC라고 말하는게 맞을 것 같습니다.

하지만, 이름과는 달리 실제로는 MVP 패턴을 사용하구요, 계층적이다보니 Presenter들 간의 통신이 필요해집니다. 바로 이부분이 제가 감명을 받은 부분이기도 하구요 ㅎㅎ

Presentation-Abstraction-Control : 요건 Hierarchical MVC하고 비슷하게 보여서 종종 연관되고는 하는데요, 사실은 근본 동기부터가 틀립니다. UI를 위한 패턴이 아닌 전체 어플리케이션의 아키텍쳐를 다루는 패턴이고, 인간의 인식 구조를 기반으로 구성했다는 것이 존경스럽네요. 저도 잘은 모르니 링크 봐주세요.

마무리

'바퀴 재발명 하기'라는 말이 있죠. 누군가 이미 잘 만들어 놓은 것을, 다시 처음부터 만들고 있는 상황을 말합니다. C++ 개발자는 특히나 바퀴를 재발명 할 일이 많은데요, 심지어는 UTF8 형식의 문자열을 다루는 표준 클래스도 없기 때문이죠 -_-;; ( 다음 표준에 생긴답니다 )
(Update. 다음 표준에 UTF8, 16, 32를 위한 리터럴이 생기고, UTF16, 32를 위한 타입이 생긴다고 합니다. UTF8은 여전히 const char* 에 저장한다는 것 같습니다. )

리스트 박스의 현재 선택된 아이템의 인덱스는 어디에 보관되야 맞을까요? 이 고민은 재작년에 한국에서 클라이언트 플랫폼을 만들때 했던 건데, 80년대의 스몰토커들도 하고 있었다니 좀 충격적이면서도 동질감이 형성되는 느낌입니다. 역시 선배님들의 업적을 공부하는 것은 중요하다는 교훈을 얻었습니다. ^^

그럼 오늘도 즐거운 코딩하시고, 위 내용중에 잘못된 것 있으면 알려주시면 감사하겠습니다~

참고 자료
http://ctrl-shift-b.com/2007/08/interactive-application-architecture.html 최고의 아티클입니다.
http://www.martinfowler.com/eaaDev/uiArchs.html 역시 최고의 아티클입니다.
http://msdn.microsoft.com/en-us/magazine/cc188690.aspx MSDN 잡지의 MS식 MVP 소개

Visual C++ 2010 Beta1

with 2 comments

[옛날 블로그 글입니다. 2009.05.28]

넵, 얼마전에 Visual Studio 2010과 .NET 4.0의 Beta1이 공개되었습니다. C++은 별 일 없겠지 싶었는데, C++0x의 일부가 수용되는 커다란 변화가 있습니다. 자세한 내용은 아래 링크에서.

http://msdn.microsoft.com/en-us/library/dd465215(VS.100).aspx

auto

이제 복잡한 타입이름을 다 적어줄 필요가 없고, auto라고 적어주면 다 된답니다.
// vector< map< int, string > >::iterator it = myVector.begin();
auto it = myVector.begin();

decltype

익스프레션을 보고 타입을 얻어낼 수 있는 녀석입니다.

int a = 0;
decltype(a) b = 1;

auto랑 연동해서 템플릿 함수의 반환값을 편하게 정의할 수 있네요.

lamda expression

람다 표현식이 좀 대박이죠. 요즘의 프로그래밍 언어들은 다 가지고 있는 클로저나 이름없는 함수 같은 녀석인데요, 함수 객체를 넘겨야하는 곳에다가 코드 조각을 직접 넘겨버릴 수 있습니다.

int count = 0;
for_each( v.begin(), v.end(), [&count] (int i) { count += i; } );

r-value reference

요건 많이 대박인데요. 임시 객체같은 r-value의 값에 대한 레퍼런스 타입이 생겼습니다. 그래서 좋은 점은 이동 생성자move constructor같은 걸 만들 수 있다는 거죠. 이동 생성자는 복사 생성자랑 비슷한데요, 복사 생성자가 deep copy를 한다면, 이동 생성자는 swap을 한다고 볼 수 있습니다.

예를 들어, 새로운 vector에는 vector의 r-value reference를 받는 이동 생성자가 있는데요, 복사생성자라면 상대편의 모든 원소를 복사하잖아요, 그런데 이동 생성자는 상대편과 자신의 내용물을 바꿔치기 해버립니다. 그러면 무지 빠르겠죠. 그리고, 이게 안전한 이유는 r-value이기 때문입니다. 다른 곳에서 참조하고 있지 않으니까요.

아래는 제가 대충 만들어본 복사생성자와 이동생성자입니다.
vector( const vector<T, A>& r ) { // Copy Constructor
size = r.size;
ptr = new T[size];
std::copy( r.ptr, r.ptr + size, ptr );
}

vector( vector<T, A>&& r ) { // Move Constructor
size = r.size;
ptr = r.ptr;

r.size = 0;
r.ptr = NULL;
}

마무리

C++이 크게 변하고 있네요. 그동안의 변화에 비한다면 올 해나 내년쯤에 발표될 새 표준은 상당히 파격적입니다. 최신 유행을 따라잡는 편리한 문법이나, 제너릭 프로그래밍을 쉽게 해주는 문법의 도입도 눈에 띄고 ( VC++ 2010은 그 중에 일부만 구현하고 있지만요)  표준 라이브러리의 확장도 기대가 큽니다.

그럼 오늘도 즐거운 프로그래밍 하시고, 다음 번에는 .NET 4.0 Beta1도 좀 포스팅 할 수 있으면 좋겠네요. 멀티 스레드 프로그래밍을 쉽게 만든 Task Parallel Libray랑 IDE 변화가 좀 재밌어 보입니다.

Written by muscly

May 28th, 2009 at 2:04 pm

MVC vs MVP

without comments

[옛날 블로그 글입니다. 2009.05.23]
[이 글은 MVC와 MVP에 대한 명확한 차이를 잘 모르고 쓴 글입니다. -_-;; ]
[MVC와 MVP에 대해 공부를 해서 비교해 놓은 글이 있으니 먼저 봐주세요~ ^^]

제가 좋아하는 구글 테스팅 블로그에 GUI 테스팅의 MVP가 되자라는 글이 있어서요. 좋은 내용이니 한 번씩 읽어보세요. 참 공감가는 얘기입니다.

설명하려면 그림은 하나 있어야겠는데, 구글 블로그에 있는 것 가져오려니 좀 찜찜하고 해서 그려봤습니다.

여기서 화살표는 데이타의 흐름이나 함수 호출이 아닙니다. 의존성이에요. 예를 들어, MVC에서 Model에서 상태 변화 이벤트가 나와서 View까지 갈 수 있지만, Model은 View를 몰라요. 의존성이 없지요. 그런 그림입니다. ( 사실 구글 블로그에 있는 그림이 더 좋아요 ㅎ)

결론은 오른쪽이 좋다는 거구요. 아무래도 의존성이 적으니 좋겠지요. View를 다른데서 재사용할 수도 있고, 유닛 테스트하기도 편하구요. 그런 얘기입니다. 구글 블로그에서 하는 말이요.

저도 참 공감합니다. 한 4년전에 C++로 MVC 기반의 라이브러리를 만들었었는데, 좀 어려웠어요. 자료도 많지 않고, 요새 나오는 언어나 프레임워크처럼 대놓고 MVC(MVP)를 지원하지도 않았구요. 그 이후로도 정답이 뭔지는 잘 몰랐습니다.

그런데, 이번에 애플의 코코아 프레임워크를 보니 MVC(MVP)를 잘 쓰고 있더군요. 그 4년전에 참고했던 돌고래 스몰토크의 구조와 비슷한 느낌이었습니다. 그 때는 잘 몰랐는데 이번엔 좀 알겠더라구요.

이번에 한 생각이 ‘아 View가 생각보다 독립적이어야 겠구나’ 입니다. OS의 커먼컨트롤들 만큼이나 순수하게 독립적이고 재사용하기 쉬운 모습의 View가 되면, MVC에서 겪은 문제들이 많이 없어지겠구나 싶었습니다. 그래서 이제야 MVC를 이해하겠구나라고 생각했었는데, 그게 아니라 MVP라는 이름으로 진화된 녀석이 있었나 봅니다. MVC와 MVP의 비교는 공부좀 해보고 다음 번에 올려보겠습니다~ ^^

Written by muscly

May 23rd, 2009 at 12:48 pm

Posted in 설계

Tagged with , , , , , ,

Test Double

without comments

[옛날 블로그 글입니다. 2009.05.22]

요새 계속 뒷북치는 글만 올리고 있네요. 요것도 좀 오래된 얘긴데요. google test 문서를 보면서 Test Double 이라는 용어가 자꾸 나와서 좀 찾아본 적이 있었습니다.

테스트를 용이하게 하려고, 진짜(Product) 오브젝트를 가짜, Fake, Dummy, Stub 오브젝트로 바뀌치는데요, 요런 용어들이 정리가 잘 안되어 있어서 Gerard라는 아저씨가 책쓰면서 좀 정리하셨다네요.
http://martinfowler.com/bliki/TestDouble.html

그래서, 그 결과는

Test Double  테스트를 위한 대역(Stunt Double이 스턴트맨 이랍니다)을 총칭
Dummy  인자나 채우려고 속셈으로 아무일도 안하는 녀석
Fake  똑같이 동작하지만 제품에는 어울리지 않는 녀석. 디비를 인메모리디비로 바꾸는 등.
Spies  호출될 때 일부 정보를 저장하는 Fake
Mocks  '이런이런 호출이 되기를 바란다'라고 미리 기대사항을 적고, 그대로 잘 됐는지 확인할 수 있는 녀석. 

Written by muscly

May 22nd, 2009 at 12:40 pm

Posted in 프로그래밍

Tagged with , , , ,

__VA_ARGS__

without comments

[옛날 블로그 글입니다. 2009.05.21]

C++에서 매크로 함수를 만들때 가변 인자(…)를 받을 수 있는 매크로입니다. C99에서 추가되었다고 하는데, GCC CPP에서는 예전부터도 다른 식으로 방법을 제공하고 있었다네요. MSVC는 2005버전부터 지원한다고 합니다. 간단한 사용예는,

#define printError( format, … ) \
    sprintf( stderr, format, __VA_ARGS__ )

지난 글의 __FUNCTION__ 매크로와 같이 쓰면 손쉽게 로깅 매크로를 만들 수 있습니다.

#define printError( format, … ) \
    sprintf( stderr, __FUNCTION__ ” ” format, __VA_ARGS__ )

위에꺼 블로그에서 그냥 쓴거라, 컴파일 안되면 말해주세요~ ㅎㅎ

Written by muscly

May 21st, 2009 at 12:38 pm