O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.
Reactive Model-View-ViewModel
모바일 응용프로그램 아키텍쳐
이규원
https://www.facebook.com/gyuwon.yi
@styletigger
MVVM
Model-View-ViewModel
MVVM(Model-View-ViewModel)
• In 2005, John Gossman(Microsoft)
• Separation of Presentation and Presentation Logic
• Two-wa...
ViewModel
Presentation Logic
View
User Interface
Model
Business Logic and
Data
2-way Binding
MVVM 응용프로그램
ViewModel
Presentation Logic
View
User Interface
API
Service
2-way Binding
Model
Server Client
서비스 클라이언트 응용프로그램
상태 동기화
State Synchronization
Showcase …
Showcase 15
no envy
Showcase …
…
… …
Showcase 15
no envy
Profile
Showcase 15
no envy
Showcase …
…
New Feed Expl...
Showcase …
Showcase 15
1 envy
Showcase …
…
… …
Showcase 15
1 envy
New Feed Explore Notifications
Profile
Showcase 15
1 env...
동기화 흐름
Flow of Synchronization
Showcase …
Showcase 15
1 envy
Showcase …
…
… …
Showcase 15
1 envy
New Feed Explore Notifications
Profile
Showcase 15
1 env...
VM
VM VM
VM VM
VM
뷰모델 사이의 데이터 흐름
ViewModelRepository
One-way
Push
Publish
One-way
단방향 데이터 흐름
Scale
Complexity
상태 동기화 복잡도
불변 모델 개체
Immutable Model Objects
ShowcaseViewModel
IsEnvied: bool
EnvyCount: int
뷰모델 속성을 통한 데이터 노출
<Button BackgroundColor="{Binding IsEnvied, Converter={...}}" />
<Label Text="{Binding EnvyCount, StringFormat='...'}" />
...
IsEnvied EnvyCount PropertyChanged Validity
False 0 Valid
True 0 "IsEnvied" Invalid
True 1 "EnvyCount" Valid
뷰모델 속성 상태 변경
뷰에 바인딩된 속성에 대한 PropertyChanged 이벤트는
레이아웃 계산과 그리기 작업을 촉발한다
모델 속성을 통한 데이터 노출
ShowcaseViewModel ShowcaseModel
IsEnvied: bool
EnvyCount: int
Model
<Button BackgroundColor="{Binding Model.IsEnvied, Converter={...}}" />
<Label Text="{Binding Model.EnvyCount, StringFormat...
Model PropertyChanged Validity
{ IsEnvied: False, EnvyCount: 0 } Valid
{ IsEnvied: True, EnvyCount: 1 } "Model" Valid
모델 상...
단, 모델 개체는 불변성을 가져야한다
Immutable Objects
• Cannot be modified after initialization
• Thread-safe
• Readability
• Runtime efficiency
• Functional ...
모델 속성을 통한 데이터 노출
ShowcaseViewModel ShowcaseModel
<< immutable >>
IsEnvied: bool
EnvyCount: int
Model
불변 모델 반응형 스트림
Reactive Streams of Immutable Model Objects
데이터 흐름
• 컨텐트 상태는 불변성을 가지는 모델 개체로 캡슐화
• 뷰모델은 모델 개체를 속성으로 뷰에 노출
• 컨텐트 상태가 변경되면 새로운 모델 인스턴스 발행
‘불변성을 가진 모델 개체의 반응형 스트림’
…
Model
Revision n + 2
Model
Revision n + 1
Model
Revision n
…
스트림 저장소
Rx(Reactive Extensions)
• Observables + LINQ + Schedulers
• Asynchronous and event-based programming
• C#, JavaScript, C, ...
반응형 스트림
public interface IObservable<out T>
{
IDisposable Subscribe(IObserver<T> observer);
}
public interface IObserver<i...
모델
public abstract class Model<TModel, TId>
where TModel : Model<TModel, TId>
where TId : IEquatable<TId>
{
private readon...
모델
public sealed class ShowcaseModel : Model<ShowcaseModel, long>
{
private readonly bool _isEnvied;
private readonly int ...
스트림 저장소
public static class StreamStore<TModel, TId>
where TModel : Model<TModel, TId>
where TId: IEquatable<TId>
{
public...
모델-뷰모델
public abstract class ModelViewModel<TModel, TId> : ViewModel
{
private TModel _model = null;
public TModel Model
{...
스트림 구독
Stream Subscription
약한 스트림 구독
ModelViewModel
Observer WeakSubscription
Stream
Reference
Weak Reference
약한 스트림 구독
public abstract class ModelViewModel<TModel, TId> : ViewModel
{
private readonly TId _id;
private readonly IObse...
스위치 연산자
Switch Operator
비동기 데이터 조회
• 응용프로그램 반응성 향상
• Futures Pattern
중복된 비동기 데이터 조회
• 불필요한 무효화(invalidation)
• 시작과 종료 순서의 불일치
Switch()
“Transforms an observable
sequence of observable sequences
into an observable sequence
producing values only from...
스위치
스위치
public abstract class ModelViewModel<TModel, TId> : ViewModel
{
private readonly Subject<IObservable<TModel>> _spout =...
Task to Observable
public abstract class ModelViewModel<TModel, TId> : ViewModel
{
protected void Push(Task<TModel> next)
...
Model to Observable
public abstract class ModelViewModel<TModel, TId> : ViewModel
{
protected void Push(TModel next)
{
Pus...
병합 연산자
Coalescing Operator
UserModel
Id : "user1"
UserName
ProfilePhotoUri
UserModel
Id: "user1"
UserName
ProfilePhotoUri
FolloweeCount
FollowerCount...
데이터 유실
UserModel
Id : "user1"
UserName
ProfilePhotoUri
UserModel
Id: "user1"
UserName
ProfilePhotoUri
FolloweeCount
Follow...
Id: "user1" UserName ProfilePhotoUri FolloweeCount FollowerCount
Id: "user1" UserName ProfilePhotoUri FolloweeCount Follow...
병합 연산
public static class ModelExtensions
{
public static UserModel Coalesce(this UserModel user, UserModel other)
{
if (u...
병합 연산
public class UserViewModel : ModelViewModel<UserModel, string>
{
protected override void OnNext(UserModel next)
{
va...
같음 확인
Equality Comparisons
뷰모델 속성 설정
public class ViewModel : INotifyPropertyChanged
{
protected bool SetProperty<T>(ref T field,
T value,
[CallerMem...
Changed!Changed…?
Showcase
Id: 15
IsEnvied: true
EnvyCount: 10
Showcase
Id: 15
IsEnvied: true
EnvyCount: 10
Showcase
Id: 1...
같음 확인 논리
public sealed class ShowcaseModel : Model<ShowcaseModel, long>, IEquatable<ShowcaseModel>
{
public bool Equals(Sh...
Changed!Changed…?
Showcase
Id: 15
IsEnvied: true
EnvyCount: 10
Showcase
Id: 15
IsEnvied: true
EnvyCount: 10
Showcase
Id: 1...
정리
Reactive MVVM Architecture
• 단방향 데이터 흐름
• 불변 모델
• 반응형 스트림
• 약한 스트림 구독
• 스위치 연산
• 병합 연산
• 같음 확인
Reactive MVVM Architecture
ViewModel Model
<< 1-way binding >>
Model
<< push >>
Coalescing
Equality
Comparison
Stream Stor...
Reactive MVVM 아키텍쳐를
적용한 안드로이드 앱을
함께 개발하실 멋쟁이
프로그래머느님을
애타게 찾고 있습니다.
public async Task<IEnvicase> CreateAndroidAsync()
{
var...
감사합니다
Reactive Model-View-ViewModel Architecture
Reactive Model-View-ViewModel Architecture
Reactive Model-View-ViewModel Architecture
Reactive Model-View-ViewModel Architecture
Reactive Model-View-ViewModel Architecture
Reactive Model-View-ViewModel Architecture
Reactive Model-View-ViewModel Architecture
Próximos SlideShares
Carregando em…5
×

Reactive Model-View-ViewModel Architecture

11.663 visualizações

Publicada em

컨텐츠 중심의 모바일 서비스 응용프로그램을 개발하기 위해 MVVM(Model-View-ViewModel) 패턴과 Rx(Reactive Extensions)를 활용해 설계한 Reactive MVVM 아키텍쳐를 설명합니다. 조금 더 자세한 설명은 블로그 포스트를 참고하세요. https://justhackem.wordpress.com/2015/03/19/rmvvm-architecture/

Publicada em: Software
  • Entre para ver os comentários

Reactive Model-View-ViewModel Architecture

  1. 1. Reactive Model-View-ViewModel 모바일 응용프로그램 아키텍쳐 이규원 https://www.facebook.com/gyuwon.yi @styletigger
  2. 2. MVVM Model-View-ViewModel
  3. 3. MVVM(Model-View-ViewModel) • In 2005, John Gossman(Microsoft) • Separation of Presentation and Presentation Logic • Two-way Binding • Properties and Commands • Testability • WPF, Silverlight, Xamarin Forms, AngularJS, EmberJS, KnockoutJS, RoboBinding • Introduction to Model/View/ViewModel pattern for building WPF apps • WPF Apps With The Model-View-ViewModel Design Pattern
  4. 4. ViewModel Presentation Logic View User Interface Model Business Logic and Data 2-way Binding MVVM 응용프로그램
  5. 5. ViewModel Presentation Logic View User Interface API Service 2-way Binding Model Server Client 서비스 클라이언트 응용프로그램
  6. 6. 상태 동기화 State Synchronization
  7. 7. Showcase … Showcase 15 no envy Showcase … … … … Showcase 15 no envy Profile Showcase 15 no envy Showcase … … New Feed Explore Notifications 단일 컨텐트에 대한 다중 뷰
  8. 8. Showcase … Showcase 15 1 envy Showcase … … … … Showcase 15 1 envy New Feed Explore Notifications Profile Showcase 15 1 envy Showcase … … 뷰 상태 동기화
  9. 9. 동기화 흐름 Flow of Synchronization
  10. 10. Showcase … Showcase 15 1 envy Showcase … … … … Showcase 15 1 envy New Feed Explore Notifications Profile Showcase 15 1 envy Showcase … … 뷰모델 사이의 데이터 흐름
  11. 11. VM VM VM VM VM VM 뷰모델 사이의 데이터 흐름
  12. 12. ViewModelRepository One-way Push Publish One-way 단방향 데이터 흐름
  13. 13. Scale Complexity 상태 동기화 복잡도
  14. 14. 불변 모델 개체 Immutable Model Objects
  15. 15. ShowcaseViewModel IsEnvied: bool EnvyCount: int 뷰모델 속성을 통한 데이터 노출
  16. 16. <Button BackgroundColor="{Binding IsEnvied, Converter={...}}" /> <Label Text="{Binding EnvyCount, StringFormat='...'}" /> 뷰모델 속성 바인딩
  17. 17. IsEnvied EnvyCount PropertyChanged Validity False 0 Valid True 0 "IsEnvied" Invalid True 1 "EnvyCount" Valid 뷰모델 속성 상태 변경
  18. 18. 뷰에 바인딩된 속성에 대한 PropertyChanged 이벤트는 레이아웃 계산과 그리기 작업을 촉발한다
  19. 19. 모델 속성을 통한 데이터 노출 ShowcaseViewModel ShowcaseModel IsEnvied: bool EnvyCount: int Model
  20. 20. <Button BackgroundColor="{Binding Model.IsEnvied, Converter={...}}" /> <Label Text="{Binding Model.EnvyCount, StringFormat='...'}" /> 모델 속성 바인딩
  21. 21. Model PropertyChanged Validity { IsEnvied: False, EnvyCount: 0 } Valid { IsEnvied: True, EnvyCount: 1 } "Model" Valid 모델 상태 변경
  22. 22. 단, 모델 개체는 불변성을 가져야한다
  23. 23. Immutable Objects • Cannot be modified after initialization • Thread-safe • Readability • Runtime efficiency • Functional programming
  24. 24. 모델 속성을 통한 데이터 노출 ShowcaseViewModel ShowcaseModel << immutable >> IsEnvied: bool EnvyCount: int Model
  25. 25. 불변 모델 반응형 스트림 Reactive Streams of Immutable Model Objects
  26. 26. 데이터 흐름 • 컨텐트 상태는 불변성을 가지는 모델 개체로 캡슐화 • 뷰모델은 모델 개체를 속성으로 뷰에 노출 • 컨텐트 상태가 변경되면 새로운 모델 인스턴스 발행
  27. 27. ‘불변성을 가진 모델 개체의 반응형 스트림’
  28. 28. … Model Revision n + 2 Model Revision n + 1 Model Revision n …
  29. 29. 스트림 저장소
  30. 30. Rx(Reactive Extensions) • Observables + LINQ + Schedulers • Asynchronous and event-based programming • C#, JavaScript, C, C++, Ruby, Python, Java • Microsoft Open Tech(*RxJava by Netflix) • https://rx.codeplex.com/
  31. 31. 반응형 스트림 public interface IObservable<out T> { IDisposable Subscribe(IObserver<T> observer); } public interface IObserver<in T> { void OnCompleted(); void OnError(Exception error); void OnNext(T value); }
  32. 32. 모델 public abstract class Model<TModel, TId> where TModel : Model<TModel, TId> where TId : IEquatable<TId> { private readonly TId _id; public TId Id { get { return _id; } } protected Model(TId id) { _id = id; } }
  33. 33. 모델 public sealed class ShowcaseModel : Model<ShowcaseModel, long> { private readonly bool _isEnvied; private readonly int _envyCount; public ShowcaseModel(long id, bool isEnvied, int envyCount) : base(id) { _isEnvied = isEnvied; _envyCount = envyCount; } public bool IsEnvied { get { return _isEnvied; } } public int EnvyCount { get { return _envyCount; } } }
  34. 34. 스트림 저장소 public static class StreamStore<TModel, TId> where TModel : Model<TModel, TId> where TId: IEquatable<TId> { public static IObservable<TModel> GetStream(TId id); public static void Push(TModel model); }
  35. 35. 모델-뷰모델 public abstract class ModelViewModel<TModel, TId> : ViewModel { private TModel _model = null; public TModel Model { get { return _model;} set { SetProperty(ref _model, value); } } protected virtual void OnNext(TModel next) { Model = next; } }
  36. 36. 스트림 구독 Stream Subscription
  37. 37. 약한 스트림 구독 ModelViewModel Observer WeakSubscription Stream Reference Weak Reference
  38. 38. 약한 스트림 구독 public abstract class ModelViewModel<TModel, TId> : ViewModel { private readonly TId _id; private readonly IObserver<TModel> _observer; private readonly IDisposable _subscription; protected ModelViewModel(TId id) { _id = id; var stream = StreamStore<TModel, TId>.GetStream(id); _observer = Observer.Create<TModel>(onNext: OnNext); _subscription = new WeakSubscription<TModel>(stream, _observer); } ~ModelViewModel() { _subscription.Dispose(); } }
  39. 39. 스위치 연산자 Switch Operator
  40. 40. 비동기 데이터 조회 • 응용프로그램 반응성 향상 • Futures Pattern
  41. 41. 중복된 비동기 데이터 조회 • 불필요한 무효화(invalidation) • 시작과 종료 순서의 불일치
  42. 42. Switch() “Transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence.” - from MSDN
  43. 43. 스위치
  44. 44. 스위치 public abstract class ModelViewModel<TModel, TId> : ViewModel { private readonly Subject<IObservable<TModel>> _spout = new Subject<IObservable<TModel>>(); protected ModelViewModel(TId id) { _spout.Switch() .Subscribe(next => StreamStore<TModel, TId>.Push(next)); } protected virtual void Push(IObservable<TModel> next) { _spout.OnNext(next); } }
  45. 45. Task to Observable public abstract class ModelViewModel<TModel, TId> : ViewModel { protected void Push(Task<TModel> next) { Push(next.ToObservable()); } protected void Push(Func<Task<TModel>> next) { Push(next.Invoke().ToObservable()); } }
  46. 46. Model to Observable public abstract class ModelViewModel<TModel, TId> : ViewModel { protected void Push(TModel next) { Push(Task.FromResult(next).ToObservable()); } }
  47. 47. 병합 연산자 Coalescing Operator
  48. 48. UserModel Id : "user1" UserName ProfilePhotoUri UserModel Id: "user1" UserName ProfilePhotoUri FolloweeCount FollowerCount Followees: 10 Followers: 24 목록 조회와 상세 정보 조회
  49. 49. 데이터 유실 UserModel Id : "user1" UserName ProfilePhotoUri UserModel Id: "user1" UserName ProfilePhotoUri FolloweeCount FollowerCount Followees: 10 Followers: 24 UserModel Id: "user1" UserName ProfilePhotoUri FolloweeCount FollowerCount Followees: 10 Followers: 24 Push User Detail Page Push User List Page Pop
  50. 50. Id: "user1" UserName ProfilePhotoUri FolloweeCount FollowerCount Id: "user1" UserName ProfilePhotoUri FolloweeCount FollowerCount Id: "user1" UserName ProfilePhotoUri FolloweeCount FollowerCount Coalesce = 병합 연산
  51. 51. 병합 연산 public static class ModelExtensions { public static UserModel Coalesce(this UserModel user, UserModel other) { if (user == null) throw new ArgumentNullException("user"); if (other == null) return user; if (other.Id != user.Id) throw new ArgumentException(); if (user.Equals(other)) return user; return new UserModel(user.Id, user.UserName, user.ProfilePhotoUri, user.FolloweeCount ?? other.FolloweeCount, user.FollowerCount ?? other.FollowerCount); } }
  52. 52. 병합 연산 public class UserViewModel : ModelViewModel<UserModel, string> { protected override void OnNext(UserModel next) { var current = Model; base.OnNext(next.Coalesce(current)); } }
  53. 53. 같음 확인 Equality Comparisons
  54. 54. 뷰모델 속성 설정 public class ViewModel : INotifyPropertyChanged { protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null) { if (EqualityComparer<T>.Default.Equals(field, value)) return false; field = value; NotifyPropertyChanged(propertyName); return true; } }
  55. 55. Changed!Changed…? Showcase Id: 15 IsEnvied: true EnvyCount: 10 Showcase Id: 15 IsEnvied: true EnvyCount: 10 Showcase Id: 15 IsEnvied: false EnvyCount: 9 Changed…? 개체 참조 비교
  56. 56. 같음 확인 논리 public sealed class ShowcaseModel : Model<ShowcaseModel, long>, IEquatable<ShowcaseModel> { public bool Equals(ShowcaseModel other) { if (other == null) return false; if (object.ReferenceEquals(this, other)) return true; return Id == other.Id && _isEnvied == other._isEnvied && _envyCount == other._envyCount; } }
  57. 57. Changed!Changed…? Showcase Id: 15 IsEnvied: true EnvyCount: 10 Showcase Id: 15 IsEnvied: true EnvyCount: 10 Showcase Id: 15 IsEnvied: false EnvyCount: 9 Not Changed 모델 데이터 비교
  58. 58. 정리
  59. 59. Reactive MVVM Architecture • 단방향 데이터 흐름 • 불변 모델 • 반응형 스트림 • 약한 스트림 구독 • 스위치 연산 • 병합 연산 • 같음 확인
  60. 60. Reactive MVVM Architecture ViewModel Model << 1-way binding >> Model << push >> Coalescing Equality Comparison Stream Store Switch Weak Subscription View Commands, Entry Fields and UI States Model << publish >>
  61. 61. Reactive MVVM 아키텍쳐를 적용한 안드로이드 앱을 함께 개발하실 멋쟁이 프로그래머느님을 애타게 찾고 있습니다. public async Task<IEnvicase> CreateAndroidAsync() { var team = await JoinUsAsync(new You()); return team.CreateAndroidApp(); } https://www.facebook.com/gyuwon.yi @styletigger gyuwon@tidcorp.com
  62. 62. 감사합니다

×