매쉬업 이미지 검색 + MVVM모델 + CommandPattern 예제

Silverlight/Lecture 2009.01.30 10:06

2009 매쉬업 경진대회 – 매쉬업 캠프 마이크로소프트 편에서 데모로 공개했던 간단한 이미지 검색 예제를
1. Open API를 이용한 MVVM모델을 고려하여 정리하고,
2. Command Pattern까지 적용한 후에,
3. Flickr, Daum, Naver 이미지 검색을 추가한...
예제를 소스와 함께 공개합니다.

스크린샷

 


라이브 데모

(콤보박스를 클릭하여 원하는 검색 서비스를 선택합니다.)
검색어를 입력하시고, 엔터를 치시거나 'Search' 버튼을 누르세요.
검색어를 변경하지 않으시고 Search를 계속해서 누르시면 추가 검색이 됩니다.



소스 다운로드

약간의 코드리뷰

소스를 다운로드 받으시고 솔루션 파일을 여시면 다음과 같은 구조를 보시게 됩니다.

View 폴더 아래에 ImageSearchView와 ImageSearchViewModel이 함께 있구요.
Model 폴더 아래 핵심이되는 Photo라는 DataModel Data를 공급하기 위한 Provider클래스들이 함께 있습니다.
Commands 폴더 아래에는 UI에서 발생하는 Event 중 CommandPattern 클래스에 DefaultCommandEvent로
지원하고 있지 않은 것에 대한 지원이 필요할 때, 추가적으로 선언하는 CommandEventRegister 클래스와
이 어플리케이션에서 지원하는 Command 목록을 정적으로 정의해 놓은 SearchCommands란 클래스가 있습니다.

Dll 폴더를 확장해 보시면,

Command Pattern 적용을 위해 HugeFlow.CommandPattern.dll을 참조하고 있습니다.
이 커맨드 패턴 라이브러리는 휴즈플로우에서 현재 차근차근 정립 중인 것이라서, 아직 다소 미진합니다.
조금 후에 설명드리는 코드들을 통해서 그냥 ‘아, 커맨드 패턴이 이런 것이구나~’ 정도만 전달이 되어도
감지덕지라고 생각합니다.

다시 Model 폴더로 돌아가서 이 중 *PhotoService란 이름을 가진 클래스들을 좀 더 살펴보면,
이들은 아래와 같은 클래스 계층(Class Hierarchy)을 갖습니다.

Live Search, Flickr, Daum, Naver 이외의 Open API 서비스들로부터
사진을 조달하도록 확장하고 싶으시면, 새로운 ????PhotoService 클래스를 추가하시고, IPhotoService
구현해 주시면 준비 완료. (10분당 서비스 1개씩 추가할 수 있었습니다.)

*PhotoService 형제 중 MockPhotoService란 녀석은 직접 데이터를 검색해 오는 것이 아니라,
하드코딩되어 있는 가짜 데이터를 공급해 주는 녀석인데요.
 
이녀석 덕분에 Blend를 통해 디자인을 하고 있는 디자이너도 다음과 같이 사진이 검색이 되었을 때의 모습을
직접 보면서, 디자인을 할 수 있습니다.



주) 현재 예제의 *PhotoService 클래스들에는 제가 직접 발급 받은 API 키들이 하드코딩 되어 있습니다.
제가 언제 API 키를 불능화할지 모르니, 이 클래스들을 참고하여 새 어플리케이션을 제작하실 때는
직접 발급받은 키를 사용해 주세요.


그럼 마지막으로 커맨드패턴 이야기 조금하고 마무리하도록 하겠습니다.

SearchCommands.cs 파일

    /// <summary>
    /// 어플리케이션 내의 커맨드를 정의하는 클래스
    /// </summary>
    public static class SearchCommands
    {
        /// <summary>
        /// 검색을 합니다.
        /// </summary>
        public static Command Search { get; set; }

        ...(중략)...

        /// <summary>
        /// 정적생성자
        /// </summary>
        static SearchCommands()
        {
            Search = new Command("Search");
            Navigate = new Command("Navigate");
            ShowLargeImage = new Command("ShowLargeImage");
            ChangeService = new Command("ChangeService");
            NavigateOriginalImage = new Command("NavigateOriginalImage");
        }
    }

지원하려는 커맨드를 이름(문자열)을 가지고 정적으로 생성합니다.
이렇게 생성된 커맨드들은 View의 Control들이 소비하게 됩니다.

ImageSearchView.xaml 파일의 최하단을 한 번 살펴보시면,
Attached Property를 통해 Control에 Command가 할당되는 모습을 보실 수 있습니다.

ImageSearchView.xaml 파일



Control을 통해 커맨드 수행 이벤트가 발생하게 되는데 이 이벤트 대한 핸들링 코드를 구현할 곳은 ViewModel입니다.

ImageSearchView.model.cs 파일을 보시면,

public ImageSearchViewModel()
{
    InitProperties();
    SearchCommands.Search.Executed += new EventHandler<HugeFlow.CommandPattern.ExecutedEventArgs>(Search_Executed);
}

void Search_Executed(object sender, HugeFlow.CommandPattern.ExecutedEventArgs e)
{
    Search((string)e.Parameter);
}

실버라이트를 이용하여 Mashup 어플리케이션을 만들어 보고자 하시는 분들에게 작은 도움이 되시길 바랍니다.
감사합니다.


설정

트랙백

댓글

  • BlogIcon 패러다임 2009.02.01 01:32 신고 ADDR 수정/삭제 답글

    정말 정말 연구해 보고 싶었던 패턴을 이렇게 만들어서 공개해 주시다니 감사합니다.

    • BlogIcon 길버트 2009.02.01 13:02 신고 수정/삭제

      안녕하세요~ 패러다임님!
      트랙백을 참고하시면 공도씨가 제 예제를 가지고,
      한단계 수준높은 Dependency Injection을 적용/설명하고 있습니다.
      공도씨 참 대단하죠?
      Dependency Injection에 대한 내용도 한번 연구해 보십시오. ^^

  • BlogIcon 열혈양군 2009.02.01 16:46 신고 ADDR 수정/삭제 답글

    아직 MVVM모델이란것이 잘 이해가 안가네요...
    MVC랑 비교하면 음...ModelView와 Control 의 차이라고 링크 거신곳에 되어있는데
    뭔차인지 잘 이해가...하하하하하~

    매쉬업을 예로하면
    Open api로 xml 데이터를 받는 클래스가 이 있다면
    그 쪽이 Model 이 되는것인가 보군요 :D

    • BlogIcon 길버트 2009.02.05 09:26 신고 수정/삭제

      맞습니다.
      데이터 클래스도 Model에 속하구요.
      데이터를 조달하는 클래스도 Model에 속합니다.

  • BlogIcon 클라인스 2009.02.04 14:21 신고 ADDR 수정/삭제 답글

    안녕하세요. 길버트님 잘 지내시죠?ㅎ
    공도님 블로그에서 MVVM+Command, DI(Ninject, Unity)를 보고 나름 이것저것 찾아서 자료를 보았는데요..정말 멋진 패턴같아요..ㅎ MVVM은 기존의 MVC의 동류?라고 볼 수있고, DI같은 경우 Factory Pattern의 동류, 확장으로 봐도 무관할 것 같아요..ㅎ
    좋은 자료 감사합니다.

    • BlogIcon 길버트 2009.02.05 09:28 신고 수정/삭제

      덕분에 잘 지내고 있습니다. ^^
      네 멋진 패턴이지요.
      저도 DI에 익숙해지려고 노력 중이예요.
      새 프로젝트에 적용해야 하거든요.

  • 나옹이 2010.06.18 17:30 신고 ADDR 수정/삭제 답글

    이제 입분한지 얼마 안되는 사람입니다.
    블로그에 와서 좋은 정보 잘보고 갑니다.
    이것이 3로 넘어와서 커맨드가 비헤이비어 형태로 들어가는건가요? 그 예제는 먼저 받았지만, 아직 보지않아 추측만해봤습니다.
    감사합니다^^

    • BlogIcon 길버트 2010.06.18 19:29 신고 수정/삭제

      실버라이트 입문을 환영합니다.

      맞습니다. 실버라이트 3부터
      커맨드를 컨트롤의 특정 이벤트와 연결할 때
      Behavior를 통해서 연결하게 되었습니다.

      이 방식의 이점은 XAML코드에 직접 Markup하지 않아도 되고,
      Blend를 통해서 추가/수정/삭제가 가능합니다.
      따라서 디자이너와 오해가 생길 여지가 없어서
      협업이 매끄럽게 진행됩니다.

      감사합니다.

  • 나옹이 2010.06.21 13:26 신고 ADDR 수정/삭제 답글

    글이 오래 되어서 덧글이 또 달릴지 몰랐습니다. Command 패턴에 대한 것을 공도님 블로그와 함께 보다가

    모두 이해하고 넘어가려고 하다가 포기하고 방금 실버라이트3에 적용된 커맨드 비헤이비어를 보고 있습니다.

    길버트님꼐서 강의를 하셨더라구요. 예전에 09년도 리믹스에서 비헤이비어를 사용했었던 동영상을 봤는데

    그때는 아무 것도 모를 때라 참 아쉽습니다. 09년 9월 자료도 실제 강의를 듣지 못한게 너무 아쉽네요.

    공부하다 모르는 부분이 생기면, 질문드려도 괜찮을까요? 그럼 좋은 한 주 되세요~^^