성배를 찾아서 – 표현과 논리의 분리
DESCRIPTION
MVVM. 성배를 찾아서 – 표현과 논리의 분리. 공인석 @ gongdo ( 주 ) 휴즈플로우. 쌍쌍바 성배 이야기. Design. Development. MVVM. is not The Holy Grail!. 선문답 ?. WHAT’S. A COMPUTER. THIS?. FOR. TO COMPUTE. TO COMPUTE. TO USE. WHAT?. TO. COMPUTER PROGRAMS. WHAT?. Input. interaction. Processing. Output. - PowerPoint PPT PresentationTRANSCRIPT
공인석@gongdo
(주)휴즈플로우* 성배를 찾아서 – 표현과 논리의
분리
MVVM
* 쌍쌍바성배 이야기
Design Development
MVVMis not TheHoly Grail!
*선문답 ?
WHAT’SA COMPUTER
THIS?
FORTO COMPUTE
WHAT?
TO COMPUTETO USE
TO
WHAT?
COMPUTER PROGRAMS
Input
Output
interactionProcessing
InputProcessing
Output
입력로직 수행표현
======
입력로직 수행
표현
CommandModel(data+logic)View*
=>=>=>
* 비주얼 표현이 목적인 애플리케이션인 경우
*뭔가 잘못된 느낌
검색
*100 만년 전
Friend[] GetMyFriends() { return null;}
silverlight 검색
검색 결과 : 0 건
앞면 뒷면
*비주얼 개발 도구의 시대
* 조립 매뉴얼은 필수
앞면 뒷면
*본격 협업의 시대
XAML
DEMO
*일반적인 UI 개발 패턴우리는 어떻게 새로운 도구를 예전과 완벽하게 똑같이 사용하는가
ViewXAML
Design,x:Name or Event
Code-Behind
Event Handlers,State,
Operations
ModelData,
Services,Business Logic
*XAML 과 코드를 속박하는 것
<Button Content="Click me" x:Name="MyButton" Click="OnMyButtonClick" />
void OnMyButtonClick(…){ MyButton.Content="Clicked!";}
XAML Code-behind
*코드 비하인드 방식의 문제
*디자인 구성 요소가 ‘문자열’ 로 코드와 강력하게 엮여 있음 .
*디자이너가 디자인 구성 요소를 자유롭게 수정하기 어려움 .
*‘ 표현’을 담당하는 View 의 코드 비하인드에 ‘표현’과 직접적인 연관이 없는 코드가 섞이게 됨 .
*디자인과 엮여 있어 ‘코드’ 부분만 따로 테스트할 수 없음 .
*간단한 인터랙션도 ‘코드’를 거치지 않고서는 ‘표현’할 수 없어 디자이너의 역할이 제한됨 .
*문제 해결 I
DEMO
*Data-binding
*속성의 변경과 데이터 반영
<UserControl x:Class="MyPage" DataContext="{StaticResource MyData}"> <TextBox Text="{Binding Path=MyText, Mode=TwoWay}"/></UserControl>
XAML
*데이터 바인딩
*데이터가 변경되거나 입력이 변경될 때마다 불필요한 코드를 작성할 필요가 없음
*코드로도 작성이 가능하지만 익스프레션 블렌드를 사용하는 것이 훨씬 더 효율적이고 원활한 협업이 가능
*특히 ItemsContrl, ListBox 의 ItemsSource 속성에 ObservableCollection 을 설정하면 매우 편리하게 컬렉션을 다룰 수 있음
*차라리 예전이 더 좋았어요 !
*단순 데이터 바인딩의 문제
*디자인 단계에서는 바인딩 한 속성에 어떤 값이 표시될지 직접 보면서 작업하는 것이 불가능
*결국 이전 처럼 ‘임시값’을 설정하여 디자인을 마치고 다시 바인딩을 설정하게 되어 더욱 복잡도가 증가
*여전히 ‘표현’이 목적인 컴포넌트가 비즈니스 로직 영역의 모델에 대해 의존적인 형태
*문제 해결 II
*Blendability
Blend 블렌드+
ability 가능한 능력
DEMO
*ViewModel 도입 !ViewModel 과 Mock-up ViewModel 을 사용한 Win-Win 전략
ViewXAML
Design
Code-BehindZero~Least-code
ModelData,
Services,Business Logic
View-ModelData,State,
Operations
DataBinding
*디자이너를 위한 초기화
if (DesignerProperties.IsInDesignTool == true){ // 디자인 모드용 Mock 데이터 설정}else{ // Runtime 용 초기화 수행}
*ViewModel:Model = 1:n?
ViewModel
View A View B VIEW C
* ViewModel 의 스콥과 라이프 사이클 문제
*ViewModel 이 View 에 대해 1:n 관계일 때 해당 ViewModel 은 지속성 persistency 을 가져야 함
*ViewModel 의 생성 시점이나 교체 시점 즉 , 라이프 사이클을 관리할 필요가 있음
*또한 ViewModel 코드에 Mock 역할을 하는 코드를 넣는 것은 불합리 하므로 Mock 역할을 하는 클래스를 따로 관리할 필요가 있음
*이에 따라 ViewModel 을 ‘관리’하는 또 다른 기능이 필요
*문제 해결 III
DEMO
*Object management간단한 Service-locator 사용
*전역 ServiceLocator 등록
<Application … 생략… xmlns:local="clr-namespace:PhotoSearch"> <Application.Resources> <local:ServiceLocator x:Key="Locator“
d:IsDataSource="True" /> <Application.Resources></Application>
*등록한 ServiceLocator 사용
<UserControl … 생략… DataContext="{Binding Source={StaticResource Locator}, Path=PhotoSearchViewModel}"></UserControl>
ViewModel A
View A View B VIEW C
ViewModel B
Model
*Interactivity
*ViewModel 에 대한 불만
*여전히 사용자의 명령에 대응하는 이벤트 처리를 코드 비하인드에서 수행*따라서 여전히 디자인 변경에 제약 , 혹은 주의가 필요
*Zero-code 실현 !
*문제 해결 IV
DEMO
*Command & Action
ViewXAML
Design
Code-BehindZero~Least-code
ModelData,
Services,Business Logic
View-ModelData,State,
Operations
CommandsDataBinding
*Command Pattern
*원래 커맨드 패턴은 애플리케이션 전역에 적용되는 ‘명령’에 적합( 예를 들어 상단에 있는 메뉴와 같은 공통 명령 )
*MVVM 과 커맨드 패턴을 조합할 때에는 ViewModel 에 해당 View에서 수행할 명령을 등록하고 바인딩하여 사용하는 것이 편리함
*기본적으로 실버라이트는 Button 에서 파생된 컨트롤만 Com-mand 를 설정할 수 있음
*그러나 InvokeCommandAction 이라는 Behavior 를 사용하여 버튼 외의 컨트롤에서도 명령을 실행 가능
*ViewModel 과 Com-manding
*public ICommand SearchCommand { get; set; }속성은 형식으로 단순히 인터페이스만 선언해도 무방
*SearchCommand = new ActionCommand(e => Search(e));와 같이 실제 커맨드가 실행되었을 때 처리할 메서드를 등록
*이 때 , e 는 CommandParameter 로 전달된 오브젝트가 됨
*버튼의 Command 속성에 위에서 선언한 Command 를 바인딩하고 CommandParameter 속성에 전달할 데이터를 바인딩
*Behavior 와 Com-manding
*Behavior 에 ICommand 타입의 속성을 만들면 해당 속성은 복수의 Trigger 로부터 InvokeCommandAction을 실행하게 됨
*복수의 이벤트로부터 동일한 명령을 실행하는 경우 편리함
*이 많은 걸 언제다…
MVVM
Data-binding
Dependency-system
Command Pattern
Behaviors
Dependency Injection
Factory Pattern
Unit Test
Observer Pattern
Event Aggregator
MVVM
Data-binding
Dependency-system
Command Pattern
Behaviors
Dependency Injection
Factory Pattern
Unit Test
Observer Pattern
Event Aggregator
MVVMis not TheHoly Grail!
DO DONT*데이터를 CRUD 할 때 최적
*동일한 데이터를 각기 다른 형식의 뷰로 보여줄 때
*같은 뷰에 여러 종류의 모델에서 받은 데이터를 보여줄 때
*동적으로 모듈이 로드 /언로드 될 때
*렌더링이 복잡한 게임
*커스텀 컨트롤을 구현할 때
*복잡한 시퀀스의 애니메이션이 더 중요할 때
*뷰와 데이터가 매우 밀접한 관계를 가질 때 ( 커스텀 컨트롤을 고려 )
*역할 균형
*References
* MVVMLight:
* http://www.galasoft.ch/mvvm/getstarted/
* 그나마 정리와 유지보수가 잘 되어 있음
* 그러나 기능상 특별히 눈에 띄는 점은 없고 SL3와 SL4를 동시 지원하면서 발생하는 불필요한 요소가 있음
* HugeFlow MVVM Library:
* http://hfcommandpattern.codeplex.com/
* 상당히 특이하고 편리한 Command 기능을 제공
* 그러나 SL3를 기반으로 작성되고 오랫동안 유지보수가 되지 않아 SL4 환경에서는 다소 불합리한 면이 있음
* 참고 링크 :
* 주의 ! 국내 자료는 대체로 SL3를 기반으로 하여 SL4에서는 더 편리하게 만들 수 있는 경우가 있음
* http://gilverlight.net/3029
* http://gilverlight.net/3018
* http://gongdosoft.com/364
Thank you!
*Image references
* http://www.flickr.com/photos/360blogroya_dayspringatyahoo/1124310204/
* http://www.flickr.com/photos/h-k-d/3875498804/
* http://www.flickr.com/photos/infomatique/3787264506/
* http://www.desktopexchange.com/gallery/Widescreen-Wallpaper/evolution_1280x768
* http://blog.daum.net/daumlove/12611660
* http://tokang.egloos.com/tag/%EC%82%BD/page/1
* http://www.flickr.com/photos/angrybee/18375774
* http://www.flickr.com/photos/lumaxart
* http://www.flickr.com/photos/markhillary/4005221302/
* http://www.flickr.com/photos/lintmachine/2987986325
* http://www.flickr.com/photos/spikenzie/3692998486
* http://www.flickr.com/photos/tangledcontrolpads/2255173714/
* http://www.flickr.com/photos/revlimit/2186764686/
우월한 이미지를생산하는 미지의 화덕
이미지 가공 코딩 또 코딩 무한 디버깅