W ostatnim artykule zwracałem uwagę między innymi na bardzo ważny element analizy i projektowania jakim jest abstrahowanie od detali, ponieważ:
…analityk musi abstrahować od wszelkich detali, bez tego projekt zostanie już na samym początku ?zabity? ich ilością. [1]
Nieco wcześniej (2013 r.) pisałem o tym, kiedy uzgadniać detale, które i gdzie one są:
Cała logika biznesowa jest wykonywana wewnątrz aplikacji (informacje o ewentualnych błędach pojawią się po zatwierdzeniu formularza), np. upust może być sprawdzony (albo naliczony) dopiero po skompletowaniu danych wymaganych do jego wyliczenia, czyli będzie to kilka różnych pól (najmniej dwa :)). Bywa, że do wyliczenia czegoś potrzebne będą dane nie wprowadzane do danej formatki faktury, np. saldo klienta. [2]
Tym razem kilka słów o tym jak skomplikować i zabić projekt już pierwszego dnia. Jednym z najbardziej ryzykownych sposobów rozpoczynania projektu jest rozpoczynanie od konsultacji z użytkownikiem w kwestii interfejsu użytkownika. Prowadzi to do sytuacji, w której jeszcze nie mamy żadnego pojęcia o logice biznesowej i architekturze aplikacji, a już deklarujemy to jak będzie się ona komunikowała z użytkownikiem (ciekawe na jakiej podstawie?).
Do napisania tego artykułu skłonił mnie ten wpis:
The role of design still puzzles many agile teams I work with. When should the design activities take place? Who should carry them out? How are design decisions best captured? This blog tries to answer the questions by discussing a user-centric, iterative, and collaborative design process for Scrum and Kanban teams. [3]
Autor pokazuje jak “walczy” ze złożonością na tym etapie, ja pragnę zasugerować by do tej złożoności na tym etapie po prostu nie dopuszczać. Powyższy diagram pokazuje z czym walczy analityk, który doprowadzi do zebrania wyrwanych z kontekstu (tak, nie ma modelu logiki więc dyskusje o GUI są oderwane od kontekstu) “wymagań” (historyjki użytkownika, lewa kolumna tablicy Story Area), których zamawiający może “naopowiadać” bardzo dużo.
A jak inaczej? Pomoże nam stosowanie wzorców architektonicznych. Są one od lat dostępne w większości frameworków (szkoda, że bardzo często developerzy je ignorują). Poniżej prosty, abstrakcyjny model klasycznego wzorca MVC.
W architekturze wydziela się komponenty (separowanie odpowiedzialności): odpowiedzialny za obsługę dialogu z użytkownikiem (View), odpowiedzialny za technologie, jakość, bezpieczeństwo, sterowanie itp. (Controler) oraz odpowiedzialny za (całą a nie tylko dane!) logikę biznesową (Model).
Zarządzanie złożonością polega tu na tym, by na początku analizy i projektowania abstrahować całkowicie od detali GUI! (a dokładnie od całej technologii czyli elementów View i Contoler). Kluczową odpowiedzialnością aplikacji jest realizacja określonej logiki biznesowej. Na tym etapie powinien powstać model przypadków użycia rozumiany jako prosty dialog pomiędzy użytkownikiem a aplikacją, tu celem jest uchwycenie kluczowych wymagań jakimi są wymagane usługi aplikacyjne realizowane przez aplikację oraz opracowanie wewnętrznej architektury – Modelu, która te usługi zrealizuje. Dopiero po przetestowaniu całej logiki biznesowej na modelach, warto się zabierać na komplikowanie projektu poprzez opracowanie detali GUI, sterowania, bezpieczeństwa itp.. Postępowanie takie umożliwia wzorzec architektoniczny MVVM opracowany ponad 10 lat temu. Wzorzec ten wprowadza dodatkowy komponent pomiędzy komponenty View i Model: View-Model, który realizuje logikę dialogu GUI-użytkownik. Dzięki temu możemy wydzielić etap pracy nad GUI, jako osobny w projekcie, który zrealizuje (później) tak zwany “UX designer”, a developer zamieni pierwotnie abstrakcyjny komponent View na implementacje “View-View Model”.
Bardzo dobry opis tego podejścia:
W przypadku warstwy prezentacji można wykorzystać m. in. następujące rozwiązania: MVC, MVP czy Model-View-ViewModel. Ze względu na mechanizm wiązań (binding), programistom WPF oraz Silverlight, polecany jest wzorzec MVVM ? jest to technologia umożliwiająca bardzo łatwą implementację wzorca. […] …po co utrudniać sobie zadanie poprzez wykorzystywanie MVVM, zamiast pisać aplikację w klasyczny sposób (za pomocą code-behind)? W końcu wdrożenie praktycznie każdego wzorca projektowego wymaga trochę większych początkowych nakładów pracy.
Podejście Code-Behind (autonomous view ? AV) ma poważną wadę ? nie gwarantuje elastyczności oraz testowalności. Podsumowując, wprowadzenie wzorca [MVVM, przypis autora] umożliwia:
- niezależność logiki od sposobu wyświetlania danych,
- niezależność kodu od technologii, w której wykonana jest warstwa prezentacji,
- wykonywanie testów ? za pomocą MVVM czy MVP możliwe jest wykonanie testów zautomatyzowanych (np. jednostkowych),
- łatwą zamianę widoków (brak sztywnych powiązań między widokiem a logiką). [4]
(Tak: stosowanie wzorców podnosi początkową pracochłonność ale zwraca się z nawiązką w dalszych cyklach życia projektu.) Strukturę i historię powstania tej architektury zainteresowani mogą poznać także tu:
Model View View Model (MVVM)
In 2005, John Gossman, Architect at Microsoft, unveiled the Model-View-ViewModel (MVVM) pattern on his blog. MVVM is identical to Fowler?s Presentation Model, in that both patterns feature an abstraction of a View, which contains a View?s state and behavior. Fowler introduced Presentation Model as a means of creating a UI platform-independent abstraction of a View, whereas Gossman introduced MVVM as a standardized way to leverage core features of WPF and Silverlight to simplify the creation of user interfaces. MVVM is a specialization of the more general PM pattern, tailor-made for the WPF and Silverlight platforms to leverage core features of WPF such as data binding, commands , templates.This diagram take from MSDN depicts MVVM Pattern in action.
Tak więc analizę i projektowanie warto zacząć od logiki i szkieletu architektury, a ta to przede wszystkim Model (dziedziny) systemu czyli kompletna logika biznesowa (utożsamianie modelu dziedziny z relacyjną bazą danych to poważny błąd i nieporozumienie). Po uporaniu się z tym etapem projektu ma sens opracowywanie detali komunikacji z użytkownikiem, bo dopiero teraz znamy wymagania i ograniczenia logiki biznesowej. Odkrywanie ich dopiero na etapie prototypowania to stanowczo za późno, bo generuje to ogromne koszty cyklicznego refaktoringu kodu (albo kod szybko staje się “bryłą błota”).
Bardzo często słyszę, że klient chce jak najszybciej coś zobaczyć. Rzecz w tym, że jeżeli się na to zgodzimy, powstaje i jest akceptowana masa tak zwanych “pobożnych życzeń”, a klient bardzo szybko się przywiązuje do tego co zobaczył na prezentacji (i nie chce odpuścić). W efekcie tworzy się spirala żądań, testów i poprawek, które szybko przekształcają “agile” w porażkę budżetu i harmonogramu. Praktyka pokazuje, że budżet zawsze ma limit, dlatego bardzo wiele takich projektów kończy albo w koszu na śmieci albo efekty stanowią tylko namiastkę tego co opisywała pierwotna wizja. Jeżeli zaś zaczniemy od jądra systemu a na koniec zostawimy sobie “makijaż” jakim jest GUI, szansa na sukces będzie znacznie większa. Problem polega na tym, że moda na “user-centric, iterative, and collaborative design” jest silna mimo tego, że jest przyczyną wielu porażek.
Tak więc odpowiedź na pytanie jak poradzić sobie z życzeniami biznesu, brzmi: nie dopuszczać do ich wyartykułowania :). Projektowanie i tworzenie samochodu rozpoczyna się od podwozia i napędu a nie od deski rozdzielczej…
Myślę że proponowane przez Ciebie podejście, tak samo jak i metoda opisana w artykule, który przytoczyłeś mogą się sprawdzić, ale jeśli stosuje się je do odpowiedniej klasy problemów. Przedstawione przez Ciebie podejście sprawdza się świetnie w biznesie, zwłaszcza takim, który już działa (jeśli nie w firmie dla której tworzymy rozwiązanie, to przynajmniej u konkurencji), problem polega wówczas na zebraniu informacji o dziedzinie problemu i uporządkowaniu ich tak, żeby tworzony przez nas system mógł jak najefektywniej działać w realiach tego biznesu. Podejście oparte na projektowaniu interfejsu może się za to sprawdzić, w projektach ?eksperymentalnych?, w których biznes jeszcze nie istnieje (albo jest bardzo trudny do poznania w inny sposób). Mamy jakąś wizję, ale jest ona w większości oparta na naszych założeniach, musimy je zweryfikować jak najszybciej i jak najniższym kosztem. Jeśli najważniejsze założenia dotyczą użytkowników systemu, to często najłatwiej zweryfikować je właśnie przez prototypowanie. Nawet fizyk teoretyczny musi czasem odejść od tablicy, by zderzać ze sobą cząsteczki i rejestrować wyniki. To jest podejście start-upów, czy prostych aplikacji narzędziowych, które mają dostarczyć grupie użytkowników nową usługę, której nie ma na rynku (albo które wykonać ją zupełnie inaczej niż konkurencja). Warto jednak pamiętać, że tak samo jak każdy fizyk wykorzystuje wyniki eksperymentu, żeby później tworzyć spójną teorię, jeśli nasz ?eksperymentalny? projekt się powiedzie i biznes wypali, warto jest zrobić kilka kroków w tył, zebrać to wszystko, czego dowiedzieliśmy się w eksperymencie, uporządkować to i sprawdzić czy gdzieś nie jest potrzebny ?refactoring? pierwotnych założeń.
Co do ostatniego zdania, warto pamiętać, że taka efemeryda nie powinna stać się ostatecznym rozwiązaniem 🙂 ….
Projektowanie i tworzenie samochodu rozpoczyna się od podwozia i napędu a nie od deski rozdzielczej?
Projektowanie samochodu zaczyna się od ustalenia ceny i zastanowienia się, czego oczekuje człowiek płacący taką a taką cenę. Czy zależy mu na stylu, parametrach czy praktyczności, a może właśnie na niskim spalaniu. Najpierw ustala się cele a dopiero po tym detale techniczne, które podwozie czy silnik wybrać. Komponenty są rozwijane niezależnie od konkretnego modelu samochodu, często przez osobne firmy (np Bosch).
Całkiem poważnie powiem: sugeruję doczytać w branży samochodowej 😉 i jakoś zdanie “Najpierw ustala się cele a dopiero po tym detale techniczne, które podwozie czy silnik wybrać.” nie pasuje do zdania pierwszego “Projektowanie i tworzenie samochodu rozpoczyna się od podwozia i napędu a nie od deski rozdzielczej?”
Produkty rynkowe: detali inżynierskie ustala się na końcu na etapie studium wykonalności…