Poprzedni artykuł kończyły słowa:
Tak więc jest to moim zdaniem droga do modelowania wymagań metodą ?tak to ma działać? a nie tylko ?tak to ma wyglądać?, bo to drugie jest przyczyną wielu problemów?
Wielu developerów zaciekle broni się przed tezą, że wymagania to także ?żądana realizacja logiki biznesowej?, oczekują wyłącznie zestawu wymagań funkcjonalnych i poza-funkcjonalnych. Jest to moim zdaniem źródło dwóch ryzyk:
- jeżeli zamówienie jest opisem czarnej skrzynki tak na prawdę nie wiemy do dostaniemy jako jej realizację,
- jeżeli autorem realizacji jest dostawca, pozostaje mu niezbywalne prawo do projektu tej realizacji.
Dlatego warto, jako wymaganie przekazać projekt tak zwanej ?białej skrzynki?, bo zabezpiecza to nas przed powyższymi ryzykami. (Wzorzec analityczny Boundary Control Entity).
Czemu tak bronię tej tezy? Zarzuty developerów wobec mnie to: „wymuszasz implementację a to rola projektanta”. Jest to nie prawda, bo projekty wymagań zawierające wewnętrzną logikę to jeszcze nie implementacja, ale na pewno jest to oczekiwanie kupującego oprogramowanie. Gdybym kupował samochód nie chciał bym, by mi ktoś powiedział, że wolno mi powiedzieć tylko jak będę do niego wsiadał, wysiadał i po co, że będę zgodnie z ogólnymi zasadami naciskał pedały i manipulował drążkiem zmiany biegów. Nie! Mam prawo i ochotą określić typ silnika, żądać ABS i wiele innych rzeczy. Jeżeli ja nie znam się aż tak na samochodach poproszę o pomoc kogoś kto się zna. Jest ryzyko? Jest, ale to ja o nim decyduję a nie sprzedawca samochodów!
Jeden z wielu powodów takiego podejścia
Przytłaczająca większość developerów, z którymi się spotkałem, rozwiązuje problem wydajności np. pracy z listą produktów, podejmując kompromis pomiędzy szczegółowością i wiernością „opisu produktu” a wydajnością (czas odpowiedzi systemu) np. podczas prezentacji (generowania) uproszczonego cennika. Większość znanych mi developerów niestety prezentuje coś co nazywam „strukturalny model projektowania oprogramowania oparty na anemicznym modelu dziedziny”. Z reguły rozwiązują oni opisany wyżej problem cennika, upraszczając opis produktu (psują model!), umieszczają uproszczone dane o produkcie w modelu relacyjnym wraz z resztą danych i walczą z optymalizacją zapytań do tej relacyjnej bazy (upraszczanie i denormalizacja).
Nie raz prowadzi to do sytuacji, w której oprogramowanie jest „szybkie i nieprzydatne”.
<–jeżeli nie jesteś analitykiem przejdź na koniec artykułu–>
Wygląda to wtedy np. tak (źr. Fowler CQRS):
Od prawej: interfejs użytkownika, model dziedziny, baza danych (podsystem utrwalania).
CQRS
Nie od dzisiaj znany jest wzorzec projektowy, który radzi sobie z tym problemem. Nazywa się CQRS, i tak jest opisywany przez „guru” analizy i projektowania :), Martina Fowlera:
CQRS stands for Command Query Responsibility Segregation. It’s a pattern that I first heard described by Greg Young. At its heart is a simple notion that you can use a different model to update information than the model you use to read information. This simple notion leads to some profound consequences for the design of information systems. (źr. CQRS).
Idea tego pomysłu na tym, by nie optymalizować wydajności systemu metodą, nie raz zgniłego, kompromisu, a podejść do problemu dzieląc go na dwa problemy: zgodność modelu z rzeczywistością i wydajność całego systemu. Pierwszy problem rozwiązujemy tworząc wierny model struktury opisującej produkty, drugi problem – wydajności – rozwiązujemy tworząc drugi uproszczony model produktów, do celów szybkiej realizacji kilku ważnych „zapytań” (np. publikacja on line uproszczonej postaci cennika).
Powyższy diagram pokazuje: UI (interfejs użytkownika), pokazuje menu zgodne z opisem z przypadków użycia (wymagania funkcjonalne). Model dziedziny (część środkowa) pokazuje oczekiwane rozwiązanie (takiego żądam w wymaganiach). Polega ono właśnie na zaprojektowaniu w części dziedzinowej odrębnego modelu do zarządzania pojedynczymi produktami i odrębnego do wydajnego zarządzania ich kolekcją. Owszem, model się nieco skomplikował (jest nieco kosztowniejszy w implementacji), ale jako zamawiający mam to czego potrzebuję: wydajny i użyteczny system.
<–jeżeli nie jesteś analitykiem tu zacznij czytać dalej–>
Opisując wymagania wyłącznie jako „czarną skrzynkę” nie wiem co dostanę. Większość developerów będzie dążyło do uproszczenia implementacji (ich koszt, nie raz brak wiedzy) by zaspokoić na minimalnym poziomie wymagania opisane przypadkami użycia. Nie raz klient słyszy „tu musimy to uprościć bo tak się nie da”, a zamawiający, nie mając kompetencji by polemizować z taką opinią, zgadza się i dostarczony w efekcie system staje się zgniłym kompromisem opartym właśnie na „czarnej skrzynce” jako specyfikacji zamówień: „dostaliśmy dokładnie to co zamówiliśmy ale zupełnie nie to czego naprawdę potrzebujemy”.
Tak więc,
nie ma znaczenia fakt, że na pewno są na rynku developerzy znający problem, który opisałem i stosujący opisane tu rozwiązanie takich problemów. Jednak nawet cień ryzyka (a jest ono na prawdę duże), że dostaniemy bubla, daje zamawiającemu prawo do szczegółowego definiowania wymagań jako „białej skrzynki”, bo dzięki temu zamawiający dostanie „to czego potrzebuje a nie tylko to co zamówił„.
Dla zainteresowanych także do pobrania książka z MSDN:
The CQRS pattern and event sourcing are not mere simplistic solutions to the problems associated with large-scale, distributed systems. By providing you with both a working application and written guidance, we expect you’ll be well prepared to embark on your own CQRS journey. (za CQRS Journey).
Cześć,
Jak dla mnie, to zdanie ?dostaliśmy dokładnie to co zamówiliśmy ale zupełnie nie to czego naprawdę potrzebujemy? jest dokładnym przeciwieństwem Twojej tezy, i świadczy o tym, że funkcjonalne wymagania nie były na pierwszym miejscu… Zamawiający powinien sprecyzować 'co potrzebuje’ i na koniec ocenić czy to co otrzymał spełnia jego wymagania. To co opisujesz, świadczy o tym, że zamawiający określił 'co i jak zbudować’ a nie 'co i jak ma działać’.
Kupując samochód nie interesuje Cię jak zbudowana jest skrzynia DSG, tylko mówisz że 'chcę żeby biegi się poprawnie same zmieniały’ 🙂
Swoją drogą, Fowler akurat dosyć krytycznie opisuje CQRS jako 'źródło problemów/komplikacji w większości projektów w których to widział’, prawda?
Oddzielmy dwie rzeczy: sposób opisania wymagań i to czym jest command Separation (w tym CQRS).
Co do wymagań to przede wszystkim: wymaganiem stolarza jest: (1) rysunek techniczny (lub szkic) młotka czy (2) opowieści stolarza o potrzebie przybijaniu gwoździ i wybijania szyb? To zależy od podejścia, MDA/MDE nie uznaje za wymagania czegoś co jest tego do czego i jak użyje użytkownik. User story to nie wymagania a co najwyżej testy (wymagania na dom dla developera to projekt architektoniczny a nie opis życia i zwyczajów rodziny).
Co do CQRS, Fowler (i nie tylko) opisał i ideę i częstą implementację. Jeżeli mamy jeden system tablic relacyjnych i do nich się odwołujemy na kilka sposobów, to to nie jest CQRS (nie ma separacji tablic są to te same relacyjne tablice). Separacja (w szczególności obiektowa) polega na tym, że np. o tej samej części samochodowej informacje trzymamy osobno w agregatach zawierających szczegóły opisu i osobno obiektach pozwalających szybko znaleźć właściwa część. Innymi słowy: magazynier ma prosty zeszycik do szybkiego znajdywania części na bazie nazwy, marki samochodu i rocznika oraz szafę z osobnymi książkami opisującymi dokładnie każdą z tych części. Całość stanowi zestaw: i zeszycik i dokumentacja (książki) na unikalny index każdej części, zeszycik służy do szybkiego identyfikowania części a książki do czerpania z nich detalicznych opisów. Tam gdzie logika (nawet napisana obiektowo) pracuje z jedną relacyjną bazą nie ma mowy o obiektowości, hermetyzacji itp… o CQRS też.. Bo zamiast separowanych dziedzinowych repozytoriów masz jedno: tę relacyjną, pozbawioną redundancji, bazę danych.
To co widzę jako przyczynę problemów wielu projektów to teza „Zamawiający powinien sprecyzować ?co potrzebuje? i na koniec ocenić czy to co otrzymał spełnia jego wymagania.” czyni z Zamawiającego projektanta a ten nie ma kompetencji do tego: piekarz piecze a nie konstruuje piece chlebowe… Pomiędzy piekarza a fabrykę sprzętu AGD należy wstawić projektanta… Chyba, że zakładamy, że – podobnie jak na rynku nieruchomości – inwestor najpierw angażuje architekta a potem developera.. wtedy OK.
Przechodząc do analogii budowlanych, klient mówi ile chce mieć pokoi i z której strony taras, a nie dostarcza rysunków technicznych czy projektu. W firmie budowlanej zaś, ktoś przygotowuje na podstawie wymagań projekt a majstrowie na podstawie tego projektu kładą cegły i rury itd. W oprogramowaniu też przecież jest architekt który projektuje system i developerzy którzy wprowadzają projekt w życie, jedni front end, inni kanalizację:)
Może to tylko różnice semantyczne.
A co sądzisz o podejściu, w którym separację szczegółu od ogółu w ramach jednej bazy danych uzyskuje się za pomocą osobny tabel?
Np, masz tabele Product, Maker, Function. Każda z nich ma rozmaite szczegóły odnośnie tych obiektów, ale masz też tabelę 'ProductSummary’, która zawiera tylko ogólne FK, info o produkcie, nazwę twórcy i nazwę funkcji?
„Przechodząc do analogii budowlanych, klient mówi ile chce mieć pokoi i z której strony taras, a nie dostarcza rysunków technicznych czy projektu.”
nie prawda, w tej branży musi…
Od lat nie stosuję relacyjnego modelu danych ;), ale osobne tabele są ok, pojęcie „baza danych” to serwer RDBMS czy system powiązanych tabel? 😉
Baza w rozumieniu MS SQL Server, czyli system powiązanych tabel + dodatkowe elementy typu procedury, funkcje, infrastruktura 'security’ itd. Wydaje mi się, że CQRS wraz z Event Sourcingiem są pewnym przerostem formy nad potrzebami w systemie który sobie tworzę – chyba zdecyduję się na prostsze podejście z repository + unit of work. Czytałem też o podejściu w którym tworzy się jakby osobne repository service / provider właśnie dla takiego odchudzonego modelu 'do raportów’…
Używanie obecnie RDMS/SQL jako narzędzie tworzenia aplikacji nie jest dobrym pomyłem.
proponuje lekturę Evansa Domain Driven Design, tak działa obecnie większość frameworków. Do raportów są tablice BI a nie bazy operacyjne 😉
Dzięki, na pewno sprawdzę ten temat… Aczkolwiek może trochę później, mam nadzieje że przy dobrze zaprojektowanej warstwie interfejsów infrastruktury podmiana warstwy dostępu do danych nie będzie wymagała dużych zmian;)
czytaj przed publikacją. Tu są błędy ortograficzne i literówki.
dwa znalazłem… 🙁 ..
Ciekawy artykuł o CQRS i jasno opisaną architekturą:
https://dotnetomaniak.pl/CQRS-and-Event-Sourcing-Intro-For-Developers-Software-House-ASC
Hej, Jeśli ktoś z Was szuka przykładu aplikacji napisanej z wykorzystaniem CQRS to polecam ten artykuł
W treści tego post’a możecie znaleźć link to całego projektu na Github.com