Tizen .Net Xamarin.Forms - MVVM 적용 타이젠 Tizen 2020. 7. 16. 22:56

Tizen에서 구동하는 .Net Xamarin.Forms Application을 잘 만드는 방법에 대한 고민으로 MVVM 패턴에 대한 이야기를 해볼까 한다.

앱 개발에는 MVC, MVP, MVVM등 다양한 소프트웨어 아키텍쳐 패턴이 사용된다. Architecture Pattern은 말그대로 많이 쓰여서 패턴화 되어있는 SW 구조라고 생각하면 된다. 디자인 패턴에 대해서도 몇번 언급을 했는데, 패턴은 그냥 써도 중간 이상이지만 잘 알고 쓰면 150점이다. MVC, MVP, MVVM 모두 변하는 것과 변하지 않는 것을 분리하고, 그것을 통해 Decoupling 된 모듈로 변화에 쉽게 대응할 수 있는 구조를 만들기 위한 고민의 산물이다.

21분이면 읽을 수 있다고 한다. 이해할 수 있다는 뜻은 아님.

좋은 설명이 많으니까 링크로 설명을 대체한다. 선정 기준은 그림이 참신했다.ㅋ Android-MVVM

Enterprise Application Pattern 소개

나도 배우는 입장이라 설명은 잘 못하겠고, 좋은 책을 하나 더 소개 한다. 무료이며, 코드도 함께 제공한다. 이게 진짜 짱이라고 생각되는 이유는, 그냥 샘플 코드로 원론적인 것을 설명하는 것이 아니다. 실제 상용 프로그램을 만들때 고민되는 내용들 잘 정리했다. mobile, web client부터 back-end 까지! 강력 추천한다. 다 읽으면 혼자 회사 하나 차릴 수 있게 된다.

Enterprise Application Pattern

MVVM 핵심

MVVM의 핵심을 몇 가지만 정리해 보자면, V -> VM -> M 이 방향으로만 의존성을 갖을 수 있다. VM은 V를 모르고, M은 VM을 모른다. 애초에 하위 레이어는 구현체가 없다고 생각하고 구현하면 된다.

View는 UI, View Model UI 로직, Model은 비즈니스 로직!

각각의 레이어는 철저히 분리되어 있으므로, 변화에 유연하게 대처할 수 있고, 독립적으로 테스트하기에도 좋다.

View에는 로직을 구현하지 않는다. code-behind를 쓰지 않고, 모든 로직은 ViewModel로 이관한다. ViewModel에서 로직을 구현하고 그 로직과 연계를 위해서 CommandBehavior를 사용 할 수 있다.

View Model에서는 data binding을 활용해서 적절하게 View와 상호 작용하기 위해 INotifyPropertyChanged를 잘 사용한다. 아래와 같이 BasePageModel 만들어서 많이들 쓰는듯.

    public class BasePageModel : INotifyPropertyChanged
    {
        protected bool SetProperty<T>(ref T backingStore, T value,
            [CallerMemberName] string propertyName = "",
            Action onChanged = null)
        {
            if (EqualityComparer<T>.Default.Equals(backingStore, value))
            {
                return false;
            }

            backingStore = value;
            onChanged?.Invoke();
            OnPropertyChanged(propertyName);
            return true;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

Property 업데이트 할 때는 이렇게 쓰면 된다.

    public int Progress
    {
        get
        {
            return _progress;
        }
        set
        {
            SetProperty(ref _progress, value);
        }
    }

컬렉션의 경우, ObservableCollection를 사용하면 좋다.

Command 사용

View에서의 입력되는 사용자의 동작에 대해서 적절하게 처리하기 위해서 로직이 필요한데, 로직은 View에 Coupling 되지 않도록 한다. 두가지 방법이 제시되고 있는데, ICommand를 통해서 이벤트를 View Model로 전달하는 것과 Behavior를 이용해서 View의 이벤트를 받아서 처리해주는 로직을 붙여주는 것이다.

ICommand는 간단하다. 인터페이스를 View Model에 구현하고, 바인딩하면 된다. 예제에서는 MainPage에 아래와 같은 버튼을 만들었다.

    <Button Text="Start"
        VerticalOptions="CenterAndExpand"
        HorizontalOptions="Center"
        IsVisible="{Binding ButtonShow}"
        Command="{Binding GoNextCommand}" />

View Model에서는 아래와 같이 구현했다.

    public ICommand GoNextCommand => new Command(GoNext);

    private void GoNext()
    {
        Application.Current.MainPage = new NavigationPage(new MainListPage());
    }

Behavior는 View Model에 구현하는 것이 아니라 별도의 클래스를 만들어서 View에 붙이는 방식이다.

마치며

정리하면서 읽으니까 족히 2시간은 넘게 걸린것 같다. 내용 자체가 아주 어렵지는 않고, 핵심적인 내용을 잘 설명하고 있으니 꼭 읽어보길.

참조

댓글