W poprzednim wpisie przedstawiłem różnice pomiędzy logiką aplikacji, a logiką biznesową. Taki podział doskonale ilustruje zasadę podziału odpowiedzialności, tzw. Separation of Concerns, w skrócie SoC.
Cofnijmy się do wspomnianego artykułu na moment i
przypomnijmy sobie główne różnice pomiędzy logiką aplikacji, a logiką
biznesową. Do zadań logiki aplikacji należy realizacja przypadków użycia, czyli kontrolowanie przepływu (flow) programu. Może znaleźć się tam
również logika odpowiedzialna za walidację np. danych wejściowych, przed
przekazaniem ich do warstwy logiki biznesowej. Logika biznesowa z kolei
odpowiada za realizację procesów
biznesowych (składanie zamówienia, obsługa płatności, wyliczanie rabatów
itp). Granica pomiędzy tymi warstwami powinna być jasno określona, tak, żeby
działanie jednej warstwy miało jak najmniejszy wpływ na działanie warstwy
drugiej.
Jak widzimy istnieje pomiędzy nimi różnica, polegająca na
tym, że każda z warstw opowiada za realizację innych zadań. Możemy więc odnieść
tę zasadę podziału odpowiedzialności do innych aspektów inżynierii
oprogramowania, takich jak:
- Programowanie komponentowe,
- Programowanie obiektowe,
- Service Oriented Applications (SOA), programowanie rozproszone,
- Wzorce warstwy prezentacji (MVC, MVVM)
W każdym z wymienionych aspektów, możemy zastosować zasadę podziału
odpowiedzialności. W jaki sposób? Na przykład w programowaniu komponentowym
staramy się tworzyć komponenty z których budowana będzie nasza aplikacja. Każdy
komponent powinien mieć jasno sprecyzowane granice (boundaries), interfejs
(kontrakt), zachowanie (metody) oraz stan, tak, żeby zminimalizować zależności
pomiędzy nimi. Dobrym przykładem takich komponentów mogą być kontrolki UI
platformy .NET, ale nie tylko. Możemy je dowolnie modyfikować, dziedzicząć po
klasach bazowych oraz umieszczać je obok siebie w oknach aplikacji. Modyfikacja
zachowania czy stanu którejkolwiek z nich nie wpłynie (lub wpłynie w minimalnym
stopniu) na działanie innych.
W programowaniu obiektowym SoC zastosujemy przy
projektowaniu modeli (zbioru klas) naszej aplikacji, np. modelu domenowego.
Tutaj łatwo pomylić zasadę SoC z zasadą pojedyńczej odpowiedzialności – Single
Responsibility Principle (SRP). W przeciwieństwie do SRP, która każe wydzielać
każdą funkcjonalność do osobnej klasy, SoC każe dzielić zagadnienie
(niekoniecznie program) na moduły, które w jak najmniejszym stopniu pokrywają
się funkcjonalnością [1]. Jak taki podział w warstwie domenowej mógłby
wyglądać? Otóż wyobraźmy sobie, że w warstwie logiki biznesowej (domenowej)
mamy obiekty odpowiadające za realizację procesów biznesowych związanych z
użytkownikiem oraz ze składaniem zamówienia. Możemy je „pogrupować” w moduły
odpowiedzialne za: obsługę użytkowników i realizację zamówień. Dzięki takiemu
„zgrupowaniu” obiektów domenowych, każdy z modułów będzie posiadał określone
granice oraz zbiór możliwych zachowań i będzie mógł być modyfikowany czy
rozwijany niezależnie od pozostałych.
W programowaniu zorientowanym na serwisy (SoA), każdy z
serwisów, może mieć jasno sprecyzowany zakres odpowiedzialności i realizować
swoje zadania niezależnie od pozostałych, np serwis płatności online, serwis
wysyłający powiadomienia email/sms, serwis udostępniający dane o produktach
itp. Aczkolwiek podobnie jak w programowaniu obiektowym różnica pomiędzy zasadą
podziału odpowiedzialności SoC, a zasadą pojedyńczej odpowiedzialności może być
bardzo płynna i niejasna.
We wzorcach prezentacji wykorzystuje się zasadę podziału
odpowiedzialności, aby oddzielić warstwę prezentacji (interfejs użytkownika) od
reszty aplikacji. Pozwala to istnieć tym warstwom niezależnie od siebie np. mogą
być rozwijane przez dwa niezależne zespoły (tzw. Front-end Developes – osoby
odpowiedzialne za UI aplikacji, oraz Back-end Developers – osoby odpowiedzialne
za logikę aplikacji, logikę biznesową, dostęp do danych itp).
Żeby nie być gołosłownym i pokazać, że zagadnienie podziału
odpowiedzialności w inżynierii oprogramowania istnieje już 40 lat, chciałem
przytoczyć cytat jednego z ojców informatyki, a inżynierii oprogrowania w ogóle
E. Dijkstry, który w swoim manuskrypcie z roku 1974 postulował dekompozycję
programu na części, z króych każda będzie dotyczyła jednego zagadnia.
Let me try to explain to you, what to my taste is
characteristic for all intelligent thinking. It is that one is willing to study
in depth an aspect of one's subject matter in isolation for the sake of its own
consistency, all the time knowing that one is occupying oneself only with one
of the aspects. We know that a program must be correct and we can study it from
that viewpoint only; we also know that it should be efficient and we can study
its efficiency on another day, so to speak. In another mood we may ask
ourselves whether, and if so: why, the program is desirable. But nothing is
gained --on the contrary!-- by tackling these various aspects simultaneously.
It is what I sometimes have called "the separation of concerns",
which, even if not perfectly possible, is yet the only available technique for
effective ordering of one's thoughts, that I know of. E. Dijkstra –
“On the role of scientific thought” (1974).
Bibliografia:
[1] K. Żydzik, T. Rak: C# 6.0 i MVC 5 Tworzenie nowoczesnych
portali internetowych. Helion 2015
Brak komentarzy:
Prześlij komentarz