sobota, 3 grudnia 2011

Budowanie z modułów - kilka słów o wzorcach konstrukcji

I. Wstęp

W tym poście chciałbym przedstawić bardzo ogólną ideę projektowania aplikacji modułowych.

W pierwszej kolejności wspomnę o tym, co będziemy rozumieli przez aplikacje modułowe czy też modularność (II. Kilka słów o modularności). Wprowadzenie jest raczej ogólne, czytelnik z choć podstawowym zrozumieniem problematyki z czystym sumieniem może je opuścić.

Dalej zajmę się przedstawieniem wybranych wzorców projektowych stosowanych w tego typu aplikacjach. Wspomnę o podstawowych elementach, które można przyjąć za charakterystyczne ogólnie dla modułów. Jak zobaczymy świetnie odzwierciedla je architektura wzorca MVVM.

Nie będę się jednak zajmował wzorcem MVVM (o którym sporo można znaleźć w innych postach tego bloga). Omówię natomiast wzorce projektowe stosowane na platformie SharePoint, która charakteryzuje się modularnością budowy.

Mimo że niniejszy blog poświęcony jest technologii .NET przykłady, ten temat będzie raczej abstrahował od konkretnej technologii. Nie szczegóły implementacji są tu istotne, ale architektura aplikacji, którą zrealizować można w sposób dowolny. Dzięki tym kilku ogólnym ideom związanym z łączeniem modułów mamy większe szanse, że nie skończymy w taki sposób:

II. Kilka słów o modularności

Co rozumiemy przez aplikację modułową? Jest to oprogramowanie złożone (surprise! surprise!) z modułów - to jest niezależnych całości. (We frameworku Prism powiedzielibyśmy, że jest to klasa implementująca interfejs IModule). Ich funkcjonalność nie zależy od kontekstu użycia. Ściślej - nie zależy od konkretnego kontekstu użycia. Moduł w różnych kontekstach może zachowywać się nieco inaczej, ale jeśli dany kontekst jest przystosowany do modułów danego typu to całość będzie funkcjonowała. Sprzężenie między modułem a kontekstem jest bardzo swobodne.

Cel jaki przyświeca tego typu architekturze aplikacji ponowne wykorzystanie raz napisanego kodu.

W przypadku modularności wchodzimy na nieco wyższy poziom ponownego wykorzystania kodu. Nasz moduł to, powiedzmy podprogram, czy miniaplikacja, która w całości może zostać zaimportowana do "składanego" programu.

Istotnie, moduły możemy potraktować jak bloczki, z których budujemy aplikację. By posłużyć się przykładem, przyjmijmy, że chcemy zrobić prostą aplikację do robienia szybkich notatek. Niech umożliwia rysowanie na prostym panelu, ale też pisanie notatek tekstowych i prostą edycję tekstu. Dalej chcielibyśmy, żeby notatkę można było przesłać dalej.

Tutaj nasz pierwszy moduł stanowiłby panel, który przyjmuje dowolny content (tekst, rysunki, zdjęcia). (Dobrym kandydatem mógłby być np. Canvas z WPF, zaimplementowany tak, by mógł przyjmować tekst z klawiatury ale miał też zaimplementowane Ink API, by użytkownik, mógł na nim rysować. Zaznaczam, że jest to tylko propozycja i szczegóły implementacji modułów nie są istotne dla omówienia idei modularności.)

Mamy panel na który wprowadzamy treść. Osobno potrzebujemy modułu, który zawierałby zestaw kilku pędzli i kilku kolorów (uproszczony paint?). Trzeci moduł to prosty edytor tekstu (kilka czcionek i ich wielkości, podkreślenie tekstu itp.)

Już teraz widać, że każdy z tych modułów może być wstawiony w inną aplika (ale tylko pod warunkiem spełnienia pewnych wymogów - o czym już za chwilę).

Mamy połączone moduły, które ze sobą współpracują i pozwalają stworzyć prostą notatkę. Wspomniałem wyżej o jeszcze jednym module - przesyłanie notatki. Nasza aplikacja zawiera miejsce na moduł przesyłu. Może on być dostosowany do przesyłania wiadomości w postaci maila (wtedy nasz moduł miałby pole np. na adres e-mail i podpis nadawcy). Ale moglibyśmy chcieć wypuścić naszą aplikację na telefon, nie zmieniamy wtedy całego programu, a jedynie podmieniamy moduł komunikacji, na taki, który przyjmuje określony typ treści i jest przystosowany do wysyłania MMSa. Inna opcja, to moduł, który konwertuje naszą notkę do rozszerzenia pdf. Rozwiązań jest sporo. Dzięki budowie modułowej jedna aplikacja może być szybko dostosowana do innej platformy, w łatwy sposób programista może też zmienić/poszerzyć jej funkcjonalność.

III. Wzorce projektowe architektury modułowej

Aplikacje modułowe wymagają nieco innego podejścia niż aplikacje, powiedzmy "klasyczne" (czyt. niemodułowe). Założeniem jest wykorzystanie bardzo dużych fragmentów już istniejących aplikacji. Moduły muszą więc mieć zbliżoną formę, przepływ danych między modułami muszą kontrolować odpowiednio zaprojektowane interfejsy itp.

Moduł aplikacji możemy rozbić na cztery elementy, od których zależy:

  1. Nawigacja - wiąże się z poruszaniem się w obrębie modułu a także między modułami

  2. Widok - czyli kwestia wyświetlania danych użytkownika

  3. Działania użytkownika - przede wszystkim praca na danych, ich aktualizacja itp.

  4. Powiązanie z danymi - osobna warstwa danych pozwala uniezależnić dane od widoku i działań użytkownika

Powyższy rozkład modułu w zasadzie niewiele różni się od WPFowego MVVM. Dlatego też ten wzorzec architektoniczny świetnie nadaje się do tworzenia aplikacji modułowych.

Szczegółowe omówienie wzorca MVVM można znaleźć w innych postach niniejszego bloga (przede wszystkim kategorie MVVM i WPF). Tutaj chciałbym się zająć mniej popularnymi wzorcami projektowymi, czy też wzorcami wyznaczającymi konstrukcję modułów, ich powiązania i role jakie spełniają. Przedstawione wzorce wykorzystywane są w aplikacjach dla platformy SharePoint.

  1. Applet Pattern - moduł w całości odpowiada za pełne przetworzenie otrzymanego obiektu. Poza tym moduł przetwarza tylko jeden typ elementów wejściowych.

  2. Tiered Pattern - moduł zbiera dane z modułów pokrewnych i łączy te dane w jedną całość. Wzorzec wymaga przejrzystej struktury każdego z modułów. Przykładowe wykorzystanie wzorca może wyglądać następująco, gdybyśmy mieli kilka modułów, zawierających różne gry planszowe, to moduł zbierający dane mógłby wyświetlać wyniki, zwycięzców itp.

  3. Personal Pattern - widok modułu składany jest z części kilku innych widoków, w zależności od użytkownika, który z niego korzysta. Taka organizacja modułu pozwala użytkownikowi swobodnie dostosować środowisko pracy do własnych preferencji. Np. w aplikacji do wysyłania wiadomości od preferencji użytkownika zależy czy załaduje do swego widoku moduł rysowania, czy tylko moduł tekstowy.

  4. Secure Separation Patterns - moduły dzielimy w zależności od poziomu bezpieczeństwa jaki jest wymagany. Informacje, do których dostęp ma tylko ich autor trzymane i przetwarzane są w jednym module. Inny służy do pracy na danych współdzielonych, jeszcze inny - do obróbki informacji publicznych. Dla aplikacji implementującej grę w karty osobny moduł służyłby do wyświetlenia kart użytkownika (wysoki poziom prywatności), w osobnym gracze widzieliby wyrzucone karty (średni poziom prywatności), a jeszcze inny pokazywałby nazwy graczy siedzących przy stoliku (poziom publiczny)

  5. Master Pattern - wzorzec zakłada jedną, wspólną warstwę danych, które są rozdzielane między różne widoki. Rozwiązanie zapewnić ma spójność danych i ich aktualność. Jest to szczególnie istotne, kiedy do danych jednoczesny dostęp ma wielu użytkowników.

  6. Knowledge Pattern - wzorzec wykorzystywany w sytuacji, kiedy moduł wykorzytuje dane przechowywane w różnych miejscach. Dostęp do danych odbywa się wtedy na różne sposoby. Moduł powinien widzieć w źródłach danych tylko te informacje, które są dla niego przeznaczone. Należy tu rozstrzygnąć, jak dane dla modułu będą oznaczane (dodatkowe tagi, osobna kolumna w tabeli itp.)

  7. Distributed Process Pattern - wzorzec powiązany z rozproszonym przetwarzaniem danych. Ideą wzorca jest zachowanie danych w jednym miejscu, podczas gdy rozproszone przetwarzanie odbywa się na rozproszonych widokach. Jednocześnie dane mogą być przetwarzane w kilku miejscach (na kilku widokach)

IV. Zakończenie

Powyższe zalecenia co do konstruowania aplikacji z gotowych modułów z powodzeniem można stosować do różnych platform i framewoków. Jak we wszystkich wzorcach projektowych szczegóły implementacji schodzą na plan dalszy. Rzeczą drugorzędną jest to czy przez moduł rozumiemy stronę internetową, region, widok, pełną aplikację itp.

W przygotowaniu tego posta bardzo pomocne były następujące artykuły:

- seria artykułów o MVVM i Prism autorstwa Marka J. Millera. Tekst o modularności dostępny pod adresem: http://www.developmentalmadness.com/archive/2009/10/15/mvvm-with-prism-101-ndash-part-3b-view-injection-and.aspx

- artykuł Modular Appliaction Design Pattersn for SharePoint utworzony przez firmę CorasWorks, a dostępny pod adresem: http://www.corasworks.net/files/DesignPatterns_White_Paper.pdf

1 komentarze:

Oskar Dudycz pisze...

Ciekawy artykuł. Fajnie, że przedstawione zostało sporo tych wzorców. Jeżeli miałbym się przyczepić do czegoś to, że opis jest dosyć ogólny, można by było zrezygnować z kilku na korzyść dodania jakiś diagramów z opisem dokładniejszym pozostałych wzorców. Mnie jako wzrokowcowi na pewno by to ułatwiło sprawę :)

Prześlij komentarz

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Online Project management