Tworzenie logiki współdzielonej cz. 2 – MVVM

W poprzednim poście mówiłem o nowym rodzaju biblioteki, jakim jest Portable Class Library. Microsoft przedstawił nam takie rozwiązanie, jeśli chodzi o tworzenie logiki aplikacji mobilnych, do którego musimy się dostosować. W poniższym poście pokaże na przykładzie, że nie jest to takie straszne, a tworzenie logiki za pomocą PCL’a może być całkiem miłe.

Wspominałem wcześniej, że do PLC-a możemy przenieść część naszych ViewModeli, jeśli są one jednakowe w obu aplikacjach (Windows Phone, Windows 8). Możemy to zrobić w prosty sposób: dodać referencję w obu projektach do biblioteki PCL. Postaram się jednak pokazać na przykładzie jak dodawać ViewModele za pomocą prostego wzorca Inversion of Control, jakie daje nam biblioteka MVVMLight.

Na początek tworzymy sobie solucję, która zawierać będzie 3 projekty:

  • PCL – biblioteka  wspólna
  • PCL.WP8 – aplikacja Windows Phone
  • PCL.W8 – aplikacja Windows Store

W ostatnich dwóch projektach dodajemy referencję do pierwszego i od tej pory możemy zacząć dewelopować.

Części wspólne

Zacznijmy więc od projektu PCL. W poprzedniej części wkleiłem obrazek który pokazywał, że w tym rodzaju biblioteki powinniśmy przechowywać modele, viewmodele i interfejsy ujednolicające API Windows Store oraz Windows Phone. Dajmy na to, że chcemy w jednym z naszych ViewModeli zapisywać i odczytywać kontekst naszej aplikacji z pliku. Na Windows Phone plik taki będziemy przechowywać w IsolatedStorage, natomiast w aplikacji Windows Store, w Storage’u dla aplikacji. W takim razie możemy stworzyć sobie interfejs IDataSerializer, który zserializuje nam obiekt konkretnej klasy.

public interface IDataSerializer
{
    Task<ApplicationContext> LoadData();

    void SaveData(ApplicationContext context);
}

Ok, problem się zaczyna, kiedy chcemy w biblitece PCL rzeczywiście coś zapisać. Przecież nie możemy napisać var serializer = new IDataSerializer(). Potrzebujemy konkretnej implementacji. Do tego właśnie posłuży nam wzorzec Inversion Of Control. Wystarczy, że dodamy do wszystkich naszych projektów jakie stworzyliśmy do tej pory bibliotekę MVVM Light Libaries only (PCL). 


mvvmlightnuget

Uważajcie żeby nie dodawać innych bibliotek MVVM Light, bo potem mogą wyniknąć problemy z referencjami.

Następnie mając już dodane wszystkie referencje możemy pobrać konkretną instancję naszego interfejsu w taki oto sposób:

var dataSerializer = ServiceLocator.Current.GetInstance<IDataSerializer>();
var appContext = await dataSerializer.LoadData();

Na chwilę obecną nie interesuje nas czy to zapisuje do pamięci telefonu czy na dysk. Pobieramy konkretną implementację i ładujemy dane. Pierwsze pytanie, jakie się nasuwa to: “Ok, ale gdzie my to wstrzykujemy”. Właśnie, żeby wstrzyknąć konkretną implementację przechodzimy na początek do aplikacji Windows Phone i wykonujemy następujące kroki:

  1. Tworzymy klasę ViewModelLocator
  2. Dodajemy statyczny konstruktor dla tej klasy i w środku wstrzykujemy naszą własną implementację zdefiniowanego wcześniej interfejsu (1):
    static ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
        SimpleIoc.Default.Register<IDataSerializer, WPDataSerializer>();  //1
    }
  3. W pliku App.xaml dodajemy do Application Resources definicję naszej klasy, aby przy starcie aplikacji wykonał się nam konstruktor:
    <Application.Resources>
        <vm:ViewModelLocator x:Key="Locator" />
    </Application.Resources>

Identyczne kroki powtarzamy dla aplikacji Windows Store, przy czym podajemy mu inną implementację naszego interfejsu.

Po wykonaniu tych 3 kroków wszystko jest już gotowe. Jeśli uruchomimy aplikacje Windows Phone, to logika w PCLu skorzysta z WPDataSerializer, natomiast jeśli uruchomimy aplikację Windows Store, ServiceLocator zwróci nam obiekt W8DataSerializer (czy jak tam go sobie nazwiemy).

ViewModele

Tutaj praktycznie kończy się nasza wiedza potrzebna do zaimplementowania PCL-a. Natomiast chciałbym również pokazać jak MVVM Light pozwala na wstrzykiwanie ViewModeli do widoków. Czasami chcemy aby dla jednej strony powstała tylko jedna instancja ViewModel i za każdym wejściem na tę stronę otwierał się ten sam obiekt, a nie nowy. Ja wcześniej to załatwiałem poprzez tworzenie statycznej właściwości w App.xaml.cs i pobierania ViewModelu stamtąd. Natomiast mając już zaimplementowane IoC możemy to zrobić w trochę inny sposób. Sposób ten działa zarówno dla WP jak i W8:

  1. W naszym pliku ViewModelLocator dodajemy (1 – jeśli chcemy stworzyć jedną instancję ViewModelu, 2 – jeśli chcemy tworzyć zawsze nową instancję)
    //1
    public HomeViewModel Home
    {
        get
        {
            return ServiceLocator.Current.GetInstance<HomeViewModel>();
        }
    }
    
    //2
    public HomeViewModel Home
    {
        get
        {
            return new HomeViewModel();
        }
    }
  2. W widoku dodajemy do głównego elementu (PhoneApplicationPage – WP, Page – W8) taki atrybut:
    DataContext="{Binding Home, Source={StaticResource Locator}}"

PS. Zacząłem tworzyć bibliotekę wystawiającą interfejsy dla podobnych części systemu Windows Phone oraz Windows 8, natomiast podczas jej pisania zauważyłem, że oba te system tak bardzo się jeszcze różnią, że nie potrafię wielu rzeczy połączyć w jeden interfejs. Możliwe, że niedługo dopiszę brakujące rzeczy i wtedy wrzucę ją na github’a.

PS2. Mam w planach nakręcić filmik pokazujący w trochę bardziej praktyczny sposób połączenie ze sobą tych dwóch aplikacji, natomiast brak czasu i brak pomysłu na taki filmik trochę mnie zatrzymuje.

Co twój język programowania o tobie mówi?

Już trochę czasu siedzę w świecie programistów i zdążyłem zauważyć pewne wzorce, to, że decyzja o wyborze języka w jakim się specjalizujesz, często wpływa na to z kim się zadajesz, a to bezpośrednio wpływa na to jaki masz charakter. Poniższy tekst jest oczywiście przebarwiony, dlatego jeśli bardzo mocno utożsamiasz się ze swoim językiem programowania nie czytaj tego.

1. Entuzjaści Open Source (Ruby)

Kiedy pytasz się ich jakiego IDE używają to patrzą na Ciebie dziwnym wzrokiem, jakby pierwszy raz słyszeli takie słowo. Do pełni szczęścia potrzebny jest im tylko dobrze skonfigurowany VIM. Z racji tego, że nie ogranicza ich system operacyjny, gdyż VIM jest dostępny na każdy system, najczęściej siedzą na iOSie albo Ubuntu. Często swoją pracę wrzucają na github-a i nierzadko biorą udział w jakichś projektach opensource-owych. Przez to, że programują nawet po pracy to mają raczej mało czasu dla rodziny i znajomych.

2. Freelanserzy (JavaScript)

Ludzie, którzy kiedyś byli zmuszeni przez szefa do użycia javascriptu w kilku projektach przez co wyżywali się pewnie na wszystkich w około. Od chwili jednak kiedy javascript stał się modny już nie narzekają (albo nie mówią tego głośno), a wychwalają brak ograniczeń w JSie.

Prawdopodobnie jedyne projekty które mają logikę w javascripcie to przykłady z których się uczą albo mały projekt dla niewielkiej sieci pizzerii. Większość programistów tworzących w javascripcie to jednak frontendowcy.

3. Apple Fanboys (objective-c)

Apple wszystko robi na przekór innym, dlatego język programowania w jakim pisane są ich aplikacje też musiał być zrobiony inaczej. Osoby, które programują w tym języku nie ruszają się nigdzie bez swojego służbowego IPhone, IPada czy MacBooka. W końcu co 5 min trzeba wrzucać info na twittera, 4square i jakieś zdjęcie na instagrama. Podświadomie mają też coś z masochistów, bo jak bardzo trzeba kochać markę, żeby zgodzić się na programowanie w języku w którym składnia jest tak bardzo powalona.

4. Korporacyjne sprzedawczyki (C#)

Uzależnienie od Microsoftu zaczyna się już w czasach studiów, kiedy to przyszli pracownicy dostają za darmo wszystko co dusza zapragnie (Visual Studio, Windows Server, SQL Servery). Darmowe wersje są idealne do małych projektów na studia. Kiedy jednak już opuszczają mury akademii są tak uzależnieni od technologii Microsoftu, że jedynym miejscem gdzie mogą nasycić swój głód są duże korporacje, które stać na zakup licencji.

Dlatego zatrudniają się w takich firmach przymykając oko nawet na to, że od czasu do czasu ktoś każe im założyć krawat. Po kilku latach spędzonych w korporacji coraz mniej programują a coraz częściej noszą krawat, aż przestają programować i nie wiedzieć kiedy budzą się jako managerowie, albo team leaderzy.

5. Jedyni prawdziwi programiści (Java)

Uważają się za jedynych prawdziwych programistów, akceptują jedynie jeszcze programistów C++. Najchętniej używają produktów, które można konfigurować edytując dane w pliku. Zwykłe checkboksy i przełączniki są zbyt ograniczające. Ponieważ uwielbiają konfigurować wszystko pod siebie nie rozumieją często użytkowników końcowych i sami od siebie dodają milion możliwości konfiguracji swoich produktów.

Większość z nich uważa Microsoft za centrum zła, dlatego kompilują 3 razy w miesiącu swoje Gentoo, tylko dlatego żeby pośmiać się na forach z lamerów używających Windowsy albo Ubuntu. Ach i cały czas pamiętają, że Microsoft okradł ich tworząc C#.

6. Hakerzy (C++)

Niewielu nowych programistów wybiera  C++, przede wszystkim dlatego, że aby napisać w nim jakiś program trzeba napisać średnio 3 razy więcej kodu niż w językach wyższego poziomu. Dla tych którzy jednak wytrwają czeka nagroda. Mogą zaliczyć się do grona prawdziwych hakerów i wyśmiewać się z tych wysokopoziomowych lamerów.  Jedyni programiści jakich akceptują to programiści C i assemblera.

Jako, że napisanie programu w C++ zajmuje również więcej czasu, firmy używają go głównie w aplikacjach, które muszą wykorzystywać specyficzne właściwości sprzętu bądź systemu. Dlatego pasja do C++ często łączy się z pasją do elektroniki i czytaniem 1000 stronicowych manuali.

7. Naukowcy (MATLAB, Clojure)

Przeważnie są to osoby, które bardziej niż programowaniem pasjonują się matematyką, a komputery uważają jedynie za duże konfigurowalne kalkulatory. Najczęściej siedzą na uczelni i piszą kolejne książki o tym jak w nowatorski sposób obliczyć transformatę furiera. Niestety ponieważ zostają na uczelni, studenci informatyki również muszą dowiedzieć się tego jak obliczać problemy matematyczne za pomocą komputera, mimo, że późniejsza praca polega jedynie na stosowaniu wzorców i nigdzie poza uczelnią nie rozwiązuje się problemów matematycznych większych niż odejmowanie od siebie dwóch dat.

Zdaje sobie sprawę z tego, że opis tych grup jest czysto subiektywny i wynika z moich spostrzeżeń w kontaktach z innymi programistami. Niemniej miałem niezłą frajdę pisząc ten artykuł :)