Tym razem wpadł mi w oko doskonały artykuł Pana Bogdana Berezy w COMPUTEROWRLD nr. 4-1019 z tego roku. Polecam cały artykuł do przeczytania, a po prawej cytat, który obudził we mnie potrzebę uzupełnienia.
Cały artykuł dotyczy ignorowania nauki w inżynierii oprogramowania na rzecz prostych pseudorozwiązań. Tu się z autorem w pełni zgadzam: nauka jako szukanie zrozumienia i rozwiązań problemów poprzez analizę i uogólnianie ma głęboki sens, historia pokazuje, że tak zwane metody naukowe są skuteczne (o czym nie raz tu już pisałem) ale też nielubiane bo trudne.
Autor napisał także (cytat po prawej, moim zdaniem prawdę), że nastąpiło pewne szaleństwo, które w moich oczach doprowadziło w branży IT to totalnego pomieszania pojęć (ostatni akapit cytatu obok). Nie zgodzę się jednak z tym, że „dane i funkcje, zadeklarowane wewnątrz jednej funkcji przestają istnieć, gdy się te funkcję opuści” (pierwszy akapit cytatu po prawej). Otóż w metodach obiektowych nie istnieje pojęcie „funkcji”, są operacje i metody oraz atrybuty a nie dane, a zniknąć mogą co najwyżej atrybuty obiektu (tu traktowane jako jakieś dane) pod warunkiem, że go – ten obiekt – zniszczymy. Tu chyba jednak mamy pomieszanie pojęć (dodam, że nie rozumiem stwierdzenia „funkcja zawiera funkcje i dane”).
W czym problem? Otóż należy bardzo rygorystycznie odróżnić:
- analizę obiektową (OOA – Object Oriented Analysis)
- projektowanie obiektowe (OOD – Object Oriented Design)
- programowanie obiektowe (OOP – Object Oriented Programming)
Autor artykułu, pisząc jedynie o programowanie obiektowym, w moich oczach ma rację. Co do zgodności OO z psychiką to i ja mam wątpliwości, i tu chyba faktycznie pomysłodawcy popłynęli.
Tu przypomnę kolejne ważne pojęcia:
- ogólna teoria systemów to teoria operująca pojęciem system, definiowanym jako „zbiór elementów współpracujących w określonym celu”, teoria ta w zasadzie stanowi obecnie podstawę tak zwanych metod naukowych,
- paradygmat obiektowy to traktowanie określonej rzeczywistości jako „zbioru współpracujących obiektów realizujących określone funkcje wobec swojego otoczenia”.
Jak widać są to bardzo do siebie podobne (niemalże tożsame) pojęcia. Studiując literaturę przedmiotu zaryzykuję tezę, że ta zbieżność nie jest przypadkowa :), pierwsze obiektowe języki programowania powstały w ośrodkach akademickich na potrzeby prowadzenia badań opartych o symulacje.
W świecie „ludzi IT” pojęcie „obiektowości” zostało całkowicie zawłaszczone na użytek języków programowania. Jest to w moich oczach wielka szkoda wyrządzona obiektowemu podejściu, teorii a także samej inżynierii oprogramowania. Autor ma rację pisząc, że „obiektowość” jako taka (powyższe definicje) nie ma nic wspólnego (nie tylko) z przenoszeniem danych ze stosu na stertę czy z dziedziczeniem. Ale to właśnie efekt tego zawłaszczenia (i opis implementacji „obiektowości” w językach programowania).
Gdzie zalety i sukces obiektowości?
Jednym z kluczowych czynników ryzyka projektów z obszaru inżynierii oprogramowania, tworzonego dla firm i organizacji, jest zła jakość specyfikacji wymagań. Zajmuję się o tym od lat, wszelkie (słusznie skrytykowane przez Pana Berezę) „proste metody zbierania wymagań” dają w efekcie to, co nazywane jest niekompletnością i niespójnością. Przyczyną porażek projektów programistycznych, podawaną w 100% przypadków tych porażek, jest niekompletność i nadmiarowość specyfikacji wymagań. Niekompletność to wymagania odkrywane dopiero na etapie wdrożenia, nadmiarowość to tak zwane wymagania osierocone, czyli funkcjonalności zgłoszone jako wymagane na etapie analizy wymagań i nie wykorzystywane po dostarczeniu oprogramowania. Pierwsze generują dodatkowe koszty, drugie to czyste marnotrawstwo środków. Nieodkryte wymagania dodatkowo „niszczą” pierwotny harmonogram.
Jak pomaga tu „obiektowość”? Pomaga jako metoda analizy, pomaga jako metoda projektowania, poprzedzającego specyfikowanie wymagań. W czym rzecz?
Popularna i fałszywa teza, mówiąca, że „wymagania się zbiera”, prowadzi do deklaratywnej i nieweryfikowalnej specyfikacji wymagań funkcjonalnych i poza-funkcjonlanych (przypominam wymagania odkryte i osierocone). Popularna i mityczna jakość wymagań nazywana SMART i FURPS nie daje żadnego narzędzia do testowania kompletności i niesprzeczności wymagań, więc nie da się stwierdzić, że konkretna specyfikacja wymagań jest SMART i FURPS, wcześniej niż po zakończeniu projektu. Tak więc FURPS i SMART spokojnie, moim zdaniem, można zaliczyć do tego co Pan Bereza nazywa „bzdurną mistyfikacją”, i co niejako wyjaśnia pewna filozoficzna „prawda” mówiąca: nie istnieją proste metody rozwiązywania złożonych problemów.
Sprawdzoną w inżynierii jako takiej, metodą, jest proces wytwórczy mający trzy etapy: analiza potrzeb, projektowanie i testy, wykonanie (wytworzenie) na bazie projektu. Wprowadzenie zmian w każdym następnym etapie jest przeciętnie o rząd wielkości kosztowniejsze. Wynika z tego, że inwestycja w analizę i projektowanie poprzedzające budowę, jest jak najbardziej uzasadniona. Jednak „kolekcjonowanie wymagań” to nie jest żadna analiza, to dopiero zbieranie danych do analizy.
A gdzie tu OOA, OOD, OOP?
Jak podejść do problemu „specyfikowania wymagań” z dużo mniejszym ryzykiem? Zamówić oprogramowanie na bazie projektu, a nie na bazie opisu „czarnej skrzynki”. Co projektować? Na pewnie nie wszystko. Wg. różnych szacunków, tak zwana logika biznesowa to ok. 3-5% całości kodu (który zawiera między innymi rozbudowane komponenty komunikacyjne, integracyjne, wydajnościowe, bezpieczeństwa, setki bibliotek, itp.) problem w tym, że te 3-5% kodu decyduje w 100% o przydatności aplikacji.
Analiza obiektowa (OOA) to metoda analizy i opisu przedmiotu analizowanego (np. organizacji). Projektowanie obiektowe (OOD) to metoda opisu logiki działania tego co chcemy stworzyć (narzędzie pracy). Programowanie obiektowe to jest to co przywołał Pan Bereza, jednak cechą OOP jest to, że projekt obiektowy, produkt OOD jest możliwy do implementacji „wprost” w języku obiektowym na etapie OOP. Innymi słowy wymaganiem nie jest „lista wymagań” a projekt, analogicznie jak w każdej innej inżynierii: wymaganiem wobec wykonawcy jest projekt tego co należy wykonać a nie tylko słowny opis tego czego oczekuje zamawiający.
OOA i OOD jest łączone w OOAD z tego powodu, że obiektowy opis (model) „czegoś” jest 9w metodach obiektowych) zarazem projektem „tego czegoś”. Mając obiektowy model oprogramowania (części opisującej jego biznesową logikę działania, nazywanej Modelem Dziedziny) możemy sprawdzić (przetestować) jak spełnia on wymagania funkcjonalne zanim jeszcze, powstanie znacznie droższa od projektu, implementacja. Mamy szanse, relatywnie niskim kosztem, zmienić projekt zanim uruchomimy kosztowny zespół programistów. Na bazie takiego modelu możliwe jest w ogóle wykonanie analizy wykonalności.
Metoda ta jest sprawdzona, działa, jest skuteczna. Pierwszy, głośno, napisał o tym Eric Evans w dziele Domain-Driven Design: Tackling Complexity in the Heart of Software (pisałem o tym tu: Poziomy szczegółowości wymagań ? wzorce DDD ? czyli czym jest analiza obiektowa). Problem polega na tym, że biznesowa analiza obiektowa (OOAD), dająca jako efekt model dziedziny (czyli sedno biznesowych aplikacji), wymaga zupełnie innych kompetencji (nie licząc rozumienia samej obiektowości) niż kompetencje programistów i architektów oprogramowania. Nie prawdą jest, że tylko „developer” ma tu kompetencje do projektowania oprogramowania. W obszarze analizy i modelowania „biznesu” z reguły nie ma żadnych kompetencji. Potwierdza to także obecny model kompetencji Analityka Biznesowego prezentowany przez organizację IIBA.
Tak więc obiektowość jako panaceum na problemy programistów i programowania to w moich oczach jak najbardziej wpadka. Obiektowość jako skuteczne metoda analizy „świata” i jego modelowania to sukces, ale to tylko kontynuacja rozwoju ogólnej teorii systemów. Obiektowość dała tej teorii bardzo dobre narzędzie – obiektowe metody modelowania. Specyfikowanie wymagań w postaci czarnej skrzynki się nie sprawdza, statystyki porażek projektów są niezmienne od lat. Specyfikacja wymagań w postaci projektu jest niemalże doskonała (ale tylko na tyle na ile doskonały jest projekt).
Arystoteles (jak słusznie zauważył Pan Bereza), uważał, że przedmioty cięższe spadają szybciej i miał on prawo posłużyć się heurystyką, w jego czasach fizyka nawet nie raczkowała. Nie zapominajmy jednak, że Arystoteles dał podwaliny dzisiejszych metod naukowych, tezą: prawdziwa wiedza to znajomość przyczyn.
Mamy jednak inny paradoks: Znamy statystyki mówiące, że ok. 75% projektów IT to porażki, a mimo to nadal najczęściej stosowane są metody wykorzystywane przez „większość”. To się nazywa konformizm Project Managera, który jak widać, jest silniejszy od umiejętności wyciągania wniosków: historia uczy ludzi, że historia niczego ludzi nie nauczyła…
Znamy z historii wiele przypadków, gdy przełomowe odkrycie nastąpiło przypadkiem w czasie eksperymentów gdzie uwaga była skupiona na czymś innym. I w niczym to nie ujmuje tym odkryciom.
Co do stosu i sterty, to programiści w większości (w szczególności w aplikacjach biznesowych) nie wiedzą (i nie muszą wiedzieć) jak to „tam pod spodem” działa.
Co do modelu obiektowego, to bardzo często właśnie go nie ma – zamiast tego jest model struktur danych – nazywanych błędnie obiektami, więc nie ma dużego sensu ocenianie czy dane podejście działa czy nie, jeżeli nie upewnimy się czy w obserwowanej próbce to podejście było faktycznie zastosowane, czy jedynie ktoś tak twierdzi:)
W bogatym wachlarzu technik DDD mamy zarówno techniki obiektowe, jak i proceduralne, funkcyjne, możemy dodawać DSLe, podejście deklaratywne. Cokolwiek, co powoli zbudować wspólny model problemu – wspólny dla eksperta domenowego (nie użytkownik i nie klient) i modelarza oraz implementowalny 1:1 w jednej z warstw systemu.
Z tym zbieraniem wymagań też jest problem, bo ludzie kiedyś „wymagali” szybszych koni a nie samochodów:)
„problem koni” obserwuje stale, jeżeli ktoś wymaga „konia” to znaczy, że kompletnie nie rozumie pojęcia „analiza wymagań”. Poprawna „specyfikacja wymagań” będzie raczej zawierała zapis „listonosz powinien w możliwie najkrótszym czasie dotrzeć do adresata przesyłki” i rolą analityką jest „dotarcie do tego” zapisu. Klient „wymagający” i otrzymujący konia, spokojnie może powiedzieć: „dostałem dokładnie to czego chciałem ale nie to czego potrzebuję”… Dobra analiza nie da „konia” jako wyniku… konia w specyfikacji zapisze „analityk dyktafon” a nie kompetentny analityk.
Zapraszam także 18 Marca na konferencję Wymagania, na której mam referat na ten temat.
Zgadzam się świetnie Pan to zauważył, że OOA, OOD i OOP to są całkowicie odrębne dziedziny. Naście lat temu spędziłem sporo czasu na próbie skonstruowania procesu programowania OOA->OOD->OOP i poległem. A poległem ponieważ, tak jak Pan napisał logika biznesowa to 3-5% całości kodu. Teraz uważam, że języki stricte obiektowe to niepotrzebny nadmiar kodu i czasu – dobre uzasadnienie w języku Python: http://www.youtube.com/watch?v=o9pEzgHorH0
Można powiedzieć, że MDA (modele CIM, PIM i PSM) to własnie proces OOA,OOD, OOP, ale prawdopodobnie nie ma potzreby by cały kod był pisany „obiektowo’…
Widzę, że Python pojawił się w rozważaniach. Zlecając (niewiele) zadań na pisanie dedykowanego softu staramy się unikać 'wielkich technologi’ (.net, java) na korzyść 'lżejszych’ typu właśnie Python czy Ruby.
Jak w Państwa praktyce zawodowej kończy się implementacja? Najczęściej w wyżej wymienionych 'ciężkich’ środowiskach czy trafiają się wykonawcy w językach bardziej przyjaznych dla zarówno developerów (mniej pisania) jak i klienta (potencjalnie szybciej można spodziewać się efektu)?
Przyznam, że nasza praktyka mimo, że celuje w wyżej wymienione nowoczesne 'lekkie’ języki, to kończy na php 😉 z powodu braku wykonawców. Projektów nie było dużo i były małe.
P.
Z mojego doświadczenia wynika, że stosowanie nazwanych tu „ciężkich” technologii, zależy od klasy zadania i wymagań, ta implikuje stosowanie nie tyle danego języka co frameworka, czyli takiego zestawu bibliotek, który pozwala jak najmniej pisać „od zera”.