안녕하세요. 이번에 새롭게 팀원이된 박세식이라고 합니다. 많이 부족해서 컴터앞에 앉아 이렇게 자판을 두드리고 있는 시간에도 떨림이 멈추질 않네요-_-; 앞으로 잘 부탁드리겠습니다.(따스~한 피드백 아시죠^^;)  
자~ 그럼. ASP.NET MVC에 대해 알아보도록 하겠습니다.

첫번째 시간으로 ASP.NET MVC vs ASP.NET WEB FORM 에 대해 글을 써보도록 하겠습니다. 제 포스트는 ASP.NET MVC에 관한 글입니다.^^; 그래서 이 둘의 대결구도라기 보다는 웸폼의 문제점을 짚어보고 MVC에 좋은 점에 대해서 글을 써 나가려고 합니다.


ASP.NET WEB FORM의 문제점?

ASP.NET WEB FORM은 ASP.NET 개발의 전통적인 스타일이고, 큰 스케일의 웹사이트를 좀더 간단하게 만들게 해주는 기술입니다. 웹폼은 드래그 앤 드랍으로 컨트롤들을 ASP.NET 페이지에 추가하고 그것들에 맞는 코드를 작성합니다. 이러한 개발방식이 개발자들의 마음을 끄는거죠. 그!러!나! 웹폼은,

관계가 분리되어 있지 않습니다. UI와 코드가 섞여있죠--;
● 자동적으로 테스트하는 것이 쉽지 않습니다. 런타임 시작없이 테스트하기가 어렵죠. 이는 실행환경을 쭉~ 돌면서 테스트할 수 밖에 없다는 겁니다-_-;
● 상태정보를 저장하려면 각 서버페이지의 상태를 뷰스테이트라고 하는 히든 필드값으로 클라이언트 페이지에 저장합니다.

하지만, 웹폼 개발에서의 특징인 뷰스테이트와 포스트백은 축복이자 파멸의 원인이됩니다. 뷰스테이트는 클라이언트와 서버간의 오고가는 데이터들의 상태를 히든 필드로 구성하고 있는 메커니즘으로, 이것의 크기는 무지막지하게 커질 수 있습니다. 매번 호출시 이 거대한 데이터가송수신된다니 끔찍스럽죠-_-; 특히 페이지에 데이터그리드나 그리드뷰와 같은 서버컨트롤이 포함되어있다면 한페이지 한페이지 넘길때마다 응답지연의 원인이 되어 사용자들을 기다림에 지치게 만드는거죠 OTL;; 또한 포스트백은 매번 액션에 의한 트리거로서 발생이됩니다. 그 거대한 데이터(뷰스테이트)를 어떤 액션만 취하게 되면 다시 그리게 되는거죠. 이 뷰스테이트에 대해 좀더 알아보죠.


뷰스테이트(View State)란?

뷰스테이트는 포스트백시 웸폼의 상태의 변화를 유지시켜주는 기술입니다. 일반적으로 __VIEWSTATE라는 이름의 히든 필드로 웹페이지에 위치합니다. 이 히든값은 수십 킬로바이트씩 쉽게 커질 수 있습니다. 이 뷰스테이트는 사용자가 웹 페이지를 포스트백 할 때 천천히 불려지고(다운로드), 그 히든 값의 내용을 웹 요청시에 포스트해서 요청 시간을 길어지게 합니다. ASP.NET 웹 페이지의 요청이 올 때 정확하게 무슨 일이 일어나는지를 알려면 ASP.NET 페이지의 생명주기(Life Cycle)을 알아봐야 하는데요. 잠깐 간단하게만 알아보도록 하죠^^;(어째~ 이야기가 점점 옆으로 새네요.. 언제 제자리로 돌아올지는 생각하지 말아주세요-_-;)


Asp.Net Page Life Cycle

매번 ASP.NET 웹 페이지에 의해 서버에 요청이 오면 첫째로 웹 서버는 ASP.NET 엔진으로 요청을 넘깁니다. ASP.NET 엔진은 웹 페이지의 올바른 파일 접근을 확인하는 여러 단계로 구성된 파이프라인을 통해서 사용자의 세션 정보를 얻습니다. 파이프라인의 끝에서는 요청된 웹 페이지에 상응하는 클래스를 인스턴스화하고 ProcessRequest() 메쏘드를 호출합니다. ASP.NET 페이지의 생명주기는 ProcessRequest() 를 통해서 시작됩니다. 이 메쏘드는 페이지의 컨트롤 단계를 준비합니다. 그 다음으로, 페이지와 서버는 ASP.NET 웹 페이지에 필요한 여러 단계를 하나씩 단계별로 밟게 됩니다. 이 단계들에는 뷰스테이트를 관리하고, 포스트백 이벤트를 처리하고, HTML 페이지를 렌더링하는 것들이 포함되어 있습니다.


그림 1. 페이지 생명 주기의 이벤트들
출처 : http://msdn.microsoft.com/en-us/library/ms972976.aspx

다시 뷰스테이트로 돌아와서 정리하자면, 세상에 공짜는 없습니다.(비용이 든다는거죠) 여기 뷰스테이트도 예외일 수는 없습니다^^; ASP.NET 페이지가 요청될 때마다 뷰스테이트는 두가지 성능에 관련되는 일을 합니다. 첫째는, 모든 페이지를 방문할 때 뷰스테이트는 해당 컨트롤 계층의 모든 컨트롤의 뷰스테이트를 모아서 베이스 64 인코딩으로 시리얼라이즈합니다. 여기서 생성된 스트링이 __VIEWSTATE에 값인거죠^^

반대로, 포스트백시에는 뷰스테이트를 읽엇 저장된 뷰스테이트 데이터로 디시리얼라이즈하고 컨트롤 계층구조에 있는 적절한 컨트롤러로 업데이트합니다. 두번째로, 뷰스테이트는 클라이언트가 다운로드 받아야할 웹페이지의 크기를 증가시킵니다. 원래 보여질 페이지의 데이터와는 또다른 데이터인거죠. 뷰스테이트 크기가 큰 페이지는 이 뷰스테이트의 크기가 수십 킬로바이트가 됩니다.  이것을 다운받기 위해 또 수 초나 수 분의 시간을 할애해야합니다.(이게~ 뭔가요-_-;) 또, 포스트백시에도 뷰스테이트를 웹 서버로 보내야하고, 그것 때문에 포스트백 요청시간이 증가하는 거죠.


ASP.NET MVC 알아보기

ASP.NET MVC는 모델, 뷰 그리고 컨트롤러로의 3개의 파트로 분리되어 구현됩니다.


그림 2. MVC Framework
출처 : http://dotnetslackers.com/articles/aspnet/KiggBuildingADiggCloneWithASPNETMVC1.aspx

● 뷰(View) 는 애플리케이션의 UI를 담당하고, 이는 단지 컨트롤러에 의해 애플리케이션의 데이터로 채워질 HTML 템플릿에 지나지 않습니다.
● 모델(Model) 은 UI를 렌더링하는 뷰가 사용할 애플리케이션의 객체, 즉 애플리케이션의 데이터의 비즈니스 로직을 구현합니다.
● 컨트롤러(Controller) 는 사용자 입력과 상호작용하는 응답을 핸들링합니다. 웹 요청은 컨트롤러에 의해 핸들링되고, 요청된 URL의 표현될 뷰와 적절한 데이터(모델 객체)를 결정합니다.


ASP.NET MVC의 요청 흐름도

ASP.NET MVC 애플리케이션은 웹폼과 같이 주소창에 입력된 URL이 해당서버의 디스크에 있는 페이지(파일)을 찾는것이 아닌 컨트롤러를 통한 뷰를 호출하게 됩니다. URL은 컨트롤로와 매핑이 되고 컨트롤러는 뷰를 리턴해주는 식이죠. 다음의 그림을 보시면


그림 3. 요청 흐름도
출처 : http://dotnetslackers.com/articles/aspnet/KiggBuildingADiggCloneWithASPNETMVC1.aspx

처음 사용자 요청(URL)이 들어오면 Routing Rule 에 의해 컨트롤러를 매핑시킵니다. Routing Rule 은 ASP.NET MVC 프로젝트를 생성하면 Global.asax에 정의되어 있는데요. 제 블로그에 컨트롤러를 설명하면서 Global.asax에 대해 간략하게 설명한 부분이 있는데요 참고하시기 바랍니다. 여기서도 간단히 설명드리자면, 주소는 {controller}/{action}/{id} 이런식으로 들어오게됩니다. 특정 컨트롤러의 특정 액션메쏘드의 파라미터로 id를 넘겨준다는 룰이죠. (액션메쏘드는 컨트롤러 클래스에서 public으로 제공되는 메쏘드를 가리킵니다.)

다시, 컨트롤러는 뷰에 넘겨줄 데이터를 만들 모델을 선택합니다. 선택된 모델객체는 뷰에 넘겨줄 데이터(ViewData)를 만들고, 컨트롤러가 이를 뷰에 넘겨줍니다. 마지막으로 뷰는 HTML로 렌더링해서 사용자에게 보여줌으로 하나의 흐름이 흘러가는 거죠^^;

그래서 ASP.NET MVC의 장점은?

● 모델, 뷰, 컨트롤러로 명확하게 관계과 분리되어 있어 복잡한 애플리케이션 로직을 관리하기 쉽게 해줍니다. 이로 인해 각 개발자는 MVC 패턴의 분리된 컴포넌트를 각자 개발할 수 있습니다. 페이지 단위로 되어 있는 웸폼은 비하인드 코드에서 로직을 담당하게 되는데요. 다른 두개의 페이지에서 비슷한 작업을 하게 된다해도 하나의 작업으로 사용하기가 어렵다는 거죠^^; 특정 페이지의 이벤트가 그 페이지의 비하인드 코드를 호출하기 때문에 같은 작업을 해도 저처럼 잘 모르는 사람들은 저희에게 무한한 능력(?)을 심어주는 카피 앤 페이스트 작업을 거쳐야한다는 겁니다.

● 유닛테스팅을 쉽게해줍니다. 이 유닛테스트도 M,V,C 가 각각 깔끔하게 분리되어 있어주기 때문에 가능한거죠^^; 추후에 유닛테스트가 과연 얼마나 쉬운지 알아보는 시간을 갖도록 하겠습니다.

● MVC 모델은 뷰스테이트와 포스트백을 사용하지 않습니다. 그래서, MVC는 일반적으로 웹폼에 비해 페이지 사이즈가 작습니다. 폼의 히든 필드인 뷰스테이트 데이터와 같은 불필요한 데이터가 없기 때문이죠.

● 웸폼 모델에서의 URL이 서버의 존재하는 파일을 직접 요청하는 것 대신에 REST 방식의 URL을 사용하여 URL을 간단하게 해주고, 기억하기 쉽게 해주고, SEO의 도움을 줍니다.

SEO(Search Engine Optimization) 는 검색엔진의 결과로 보여질 랭크의 순위를 높이는 작업을 말합니다. 상위 랭크의 검색결과로 나타내어지면 사용자가 아무래도 계속 그것만 보게되니 좋겠죠^^; 그래서 URL 또한 사용자가 보기 쉬운 걸로 나타내면 좋다는거죠. 예를들어, /Product/Edit/4 이런 URL 이라면 4번째 상품을 수정하겠다는 거군. 이렇게 명시적으로 알수 있다는 겁니다. 예가 좀 부적합한가요^^;

● jQuery나 ExtJS와 같은 클라이언트단 자바스크립트 프레임워크와 쉽게 통합할 수 있습니다.


마무리요

사실, 웸폼과 MVC를 비교해서 꼭 이것이 더 좋으니까 이것만 사용해야지가 아닙니다. 각 프로젝트의 특성에 맞게 선택하는 거죠. (다시한번 말씀드리지만 이 포스트는 ASP.NET MVC에 관한 글입니다--;) 성능을 따지지 않고 빠른 개발을 원한다면 웹폼을 선택하는 것이 좋을 것 같고, 유닛테스팅과 성능에 중점을 두겠다 싶으면 MVC쪽을 선택해봄이 좋겠다는 거죠. 다음 포스트에는 예제를 통해서 ASP.NET MVC와 인사를 나눠보는 시간을 갖도록 하겠습니다^^


참고자료 :
http://msdn.microsoft.com/en-us/library/ms972976.aspx
http://dotnetslackers.com/articles/aspnet/KiggBuildingADiggCloneWithASPNETMVC1.aspx
http://msdn.microsoft.com/en-us/magazine/dd942833.aspx
http://www.techbubbles.com/aspnet/aspnet-mvc-and-web-forms/
http://www.taeyo.net/lecture/NET/AspNet35_pre02.asp
http://weblogs.asp.net/shijuvarghese/archive/2008/07/09/asp-net-mvc-vs-asp-net-web-form.aspx
http://weblogs.asp.net/scottgu/archive/2007/10/14/asp-net-mvc-framework.aspx