piątek, 22 października 2010

Warsjawa 2010

Zapraszam wszystkich czytelników bloga na prezentację Domain Driven Design - Wszystko ma swoje miejsce i wszystko jest na miejscu, którą przedstawiam w najbliższą sobotę na konferencji Warsjawa.

Skrót:
Czy zastanawialiście się co jest przyczyną rozkładu średnich i dużych systemów? Czy jest on nieunikniony i jest jedynie kwestią czasu? A może jednak istnieje jakiś sposób na utrzymanie entropii w ryzach?

Podczas prezentacji zobaczymy w jaki sposób Domain Driven Design pomaga w okiełznaniu chaosu. W prezentacji znajdą się główne techniki modelowania takie jak Ubiquitous Language, Bounded Context, Strategic Design.

Zostaną przedstawione również podstawowe techniki implementacji DDD: przykłady Building Blocks, Command-query Responsibility Segregation, system zdarzeń, przypadki wykorzystania ORM i SQL - całość na przykładach w Seam lub Spring.

//===========================

Dla tych z Was, którzy byli w Krakowie na NYAC zaznaczam, że core prezentacji będzie taki sam.

czwartek, 21 października 2010

Turbo Seam

Niniejszy post rozpoczyna mini serię poświęconą Seam Framework. Zawartość to kilka przydatnych technik oraz kilka trików, które udało mi się zebrać podczas paru lat używania tego "ficzer"-worka.

Spis treści

- Produktywne środowisko developerskie. Hot deploy wszystkiego. Nawet encji (a podobno się nie da;P) W najgorszym przypadku 3 sek. na przeładowanie.
- Integracja z Maven - elegancko i bezboleśnie. Panom od JBoss Tools już podziękujemy...
- Integracja z jQuery - gdy ciężar RichFaces przygniata, narzut na komunikację AJAX osłabia a kontrolki wyglądają jak z poprzedniej epoki
- Asynchroniczny mailing w dobrym stylu - mikro architektura rozsyłania maili połączona z eleganckim decoupliniem poprzez zdarzenia
- Integracja z BIRT - speszyl haki
- Seam Gen i Seam App. Framework - dlaczego nie używać:)


Powyższa lista będzie sukcesywnie aktualizowana o linki do konkretnych postów oraz ew. nowe pozycje. Docelowo post będzie stanowił swego rodzaju spis treści.

//==============================

Generalnie do tej pory nie pisałem zbyt wielu postów technicznych - wychodząc z założenia, że w oceanie treści nie będą wnosić nic nowego.

Jednak zestawiając dwa aspekty:
- własne przemyślenia
- obserwując jak Seam jest używany
doszedłem do wniosku, że zgromadzona wiedza może się komuś przydać.

Jeżeli macie jakieś tematy, które chcielibyście poruszyć - piszcie śmiało, być może dodamy je do listy.

środa, 13 października 2010

Przyczyna całego zła

Dziś kolejny post z serii geek humor.

Prawdopodobnie odkryłem przyczynę całego zła w projektach, bałaganu, złego designu modelu obiektowego i naszego ulubionego kodu spaghetti.

Jest nią najprawdopodobniej totalnie niezrozumienie polimorfizmu!

Tutaj znajdziemy oświecenie: http://www-users.mat.umk.pl/~grzegorz/polymorphism.pdf
.. gdyby tak każdy programista się z nim zapoznał, to świat byłby lepszy;)

//===============================

Jeżeli macie jakieś ciekawe materiały edukacyjne to wklejajcie w komentarzach.

niedziela, 5 września 2010

Głuchy telefon


Głuchy telefon - intrygująca i dająca do myślenia zabawa z dzieciństwa, gdzie nawet bardzo prosta "informacja" może zostać zniekształcona po przejściu przez łańcuch "przekaźników".

Kultowy obrazek z huśtawką (który wszyscy znamy) obrazuje co dzieje się z informacją nieco bardziej wyrafinowaną (np. na temat wymagań) w procesie produkcji softu.

Jak temu zapobiec?
Racjonalnym rozwiązaniem jest Ubiquitous Language - kluczowa technika w Domain Driven Design polegająca na operowaniu wspólnym słownictwem domenowym na każdym poziomie abstrakcji: począwszy od eksperta biznesowego po kod źródłowy (sic!) w warstwie logiki aplikacji i logiki domenowej. W logice domenowej oczywiście obowiązuje ścisła "etykieta" - korzystanie z dobrze zdefiniowanych Building Blocks.

W tym miejscu dochodzimy do sedna posta.
Zachęcam do zapoznania się z prezentacją mego guru - Erica Evansa: "Sustainable Design for Agile Teams" podczas, której mamy próbkę sesji analitycznej pomiędzy programistą a ekspertem domenowym. Zwróćcie uwagę na dobrze zdefiniowany, wspólny język jakim posługują się obie strony oraz w jaki sposób "odkrywają" nowe byty.

Oczywiście taki proces nie jest tani oraz wymaga cennego zasobu: eksperta domenowego:/

//===========================================

Prezentacja porusza również inny, arcyważny aspekt: niezrozumienie projektowania domeny w naiwnym podejściu do Agile. Kiedy skupiamy się na pojedynczym wymaganiu lub na pojedynczej iteracji, wówczas zwykle mamy do czynienia ze specjalnym przypadkiem procesu biznesowego w jakiejś domenie. Gubimy "biger pikczer" i z czasem całość sprowadza się do radosnego (później smutnego) "hakowania" kodu opisującego jakieś specjalne przypadki - zaszłości. I nie ma co się oszukiwać - nikt nie jest skory do refaktoringu modelu domenowego, który jest już napełniony danymi w bazie:)

wtorek, 10 sierpnia 2010

Pomożecie?


Dzisiejszy post jest nietypowy, ponieważ zwracam się w nim do szanownego grona czytelników z prośbą o pomoc/przysługę. Zostałem zaproszony na tegoroczną konferencję JDD w roli prelegenta i zastanawiam się nad tematem, który mógłby Was potencjalnie (nawet jeżeli nie wybieracie się na konferencję, po prostu ogólnie) zainteresować.

Prezentacja poświęcona Software Craftsmanship i Wzorcom już osiągnęła limit reużywalności, dlatego zastanawiam się nad nowym tematem:) Jeżeli macie jakieś sugestie lub konkretne życzenia odnośnie tego o czym chcielibyście usłyszeć to piszcie śmiało w komentarzu lub na priv (adres w panelu "o mnie" po prawej stronie).

//===============================

Patrząc na ogólne trendy, które w tym roku widać również na polskich konferencjach, można zaobserwować, że raczej odchodzi się od zachwalania kolejnych tuzinów frameworków webowych w stronę zagadnień bardziej ogólnych, zwykle syntetyzując przekrój kilku aspektów. Ciekaw jestem co myślicie o tym trendzie.

Póki co mam pewien pomysł na prezentację poświęconą podejściom do Inversion of Control. Tak, wiem, że temat jest oklepany ale co powiecie na przegląd architektur aplikacji opartych o IoC. Przegląd będący swego rodzaju wycieczką po rozwiązaniach architektonicznych.

Najpierw zastanowilibyśmy się czym w ogóle jest architektura, jakie są jej rodzaje i czym arch. różni się od designu. Później wycieczka po kolejnych podejściach do architektur opartych o 3 techniki IoC w kolejności ich "siły".

Czyli najpierw "najsłabsze" (w sensie siły a nie w sensie, że jest kiepskie) podejście: wstrzykiwanie zależności - co i kiedy warto wstrzykiwać. Bo wstrzykiwanie DAO/Repo do Servisów jest nudne.

Dalej technika "mocniejsza" - bo abstrahująca nie tylko od typu współpracownika, ale i ich ilości oraz czasu - arch. zorientowana na zdarzenia. Przykłady wykorzystania zdarzeń do zwiększania przepustowości oraz do notowania "wydarzeń" biznesowych - wszystko w kontekście event sourcing i Command-query Responsibility Segregation.

Na zakończenie najsilniejsza technika IoC: Aspect Oriented Programming.

Na każdym "przystanku" naszej wycieczki zastanowilibyśmy się co wynika z zastosowania danego podejście i kiedy warto z niego skorzystać - a kiedy jest to tylko moda i owczy pęd.

Jak widać z opisu prezentacja była by przeznaczona dla początkujących architektów aplikacji - programistów, którzy chcieliby zając się projektowaniem w skali makro.

czwartek, 1 lipca 2010

Bo w życiu trzeba... być Agile:)


Od dzieciństwa słyszmy ze strony różnych "dobrych wujków" co jest "w życiu ważne". Niestety rzadko zdarza się usłyszeć o adaptacyjności czyli życiowej zwinności (w sensie agilności).

Jadnak jakimś cudem w IT wszyscy są Agile - jakiś czas temu robiłem mały research, podczas którego z trudem znalazłem jedną firmę, w Indiach, która otwarcie mówi, że nie jest Agile;)

Gdy jednak przyjrzeć się bliżej, to z tym Agile jest jak z seksem u nastolatków - każdy o tym mówi ale niewielu tak na prawdę to robi (a przynajmniej tak było kilkanaście lat temu w klasach mat-inf;)
Mówi się, że Agile jest trudny ponieważ z pozoru wydaje się łatwy - tak łatwy, że wszystkim wydaje się, że zrozumieli.

W niniejszym poście nie będę pisał o problemach z metodykami (przy okazji: metodologia to nauka o metodykach). Skupimy się na materii miękkiej, czyli problemach z ludźmi.

Jak często napotykacie niemal faszystowskie, anty-adaptacyjne postawy typu:

- nie pisz komentarzy, pisz samo-komentujący się kod (ale samo-komentujący z czyjego punktu widzenia?)
- dobry kod powinien mieć 70% komentarzy tak aby dało się go odtworzyć czytając je (ale po co?)



- Stories są lepsze/gorsze niż Use Case (na jakim poziomie?)


- YAGNI i KISS (nawet jeżeli mam intuicję, że się przyda?)


- Java rules/.NET rules (ale czym to się różni?)

- zawsze używajmy IoC i ORM (ale dlaczego i po co?)
- ORM to badziewie, tylko SQL w procedurach (ale jakim kosztem?)

- jak baza to tylko Oracle/Postgres/...  (ale do każdego projektu?)
- jak baza to tylko noSQL (bo jest sexi?)

 - zawsze pisz testy - "you are not allowed to write a single line of production code without test first" - grzmiał jakiś czas temu Uncle (nomen omen;) Bob
- powinieneś mieć co najmniej 80% pokrycia testami (a dlaczego nie 85%? settery też?)
- nie pisz testów nigdy (nigdy?!?)

- metody powinny mieć 5 linijek (za 6 pójdę do więzienia?)
- metody powinny być tak długie, że powinno dać się je zrozumieć w 5 minut (ale zrozumieć przez kogo)

- zawsze używaj Mavena (nawet w jednomodułowym projekcie z 10 libami?)

- statyczne języki są lepsze (lepsze do czego?)
- dynamiczne języki są lepsze (szczególnie jak do klasy String dokleję sobie 150 metod



- przeglądarka/system/IDE X jest lepsze (lepsze do czego? mówisz to aby pomóc czy aby się podroczyć?)

Można by tak mnożyć w nieskończoność...

Nie wiem czy jest to przypadłość jedynie naszej branży, ale tym co hamuje Agile w procesie jest Autorytaryzm w ludziach. Być może autorytaryzm jest ogólnym memem "odziedziczonym" po wspomnianych w pierwszych zdaniu wujaszkach. Być może jest on wbudowany w nasze ścisłe umysły jako ich integralny ficzer - taki koprocesor poszukiwania jednego, naiwnie prostego równania na wszystko.


O ile mamy coraz więcej KNOW HOW to często brakuje KNOW WHEN.


Można ująć to inaczej: w równaniu

Mądrość = Wiedza + Kontekst

najważniejszy jest kontekst. Kontekst jest tym co odróżnia teorię od praktyki. Kontekst pozwalający zaadaptować wiedzę. Kontekst, który w Modelu Kompetencji Braci Dreyfus pojawia się z czasem, z doświadczeniem. A doświadczenie to refleksja. Refleksja jest konieczna do adaptacji podejścia.


//=================================

W większości cywilizacji konsekwencja jest cnotą. Zwrot "nie jesteś konsekwentny w swym postępowaniu" ma mocno pejoratywny wydźwięk.

Ale bardziej Agile jest inne podejście - podejście adaptacyjne: "Konsekwencja jest fortecą głupców". Konsekwencja zwalnia z obserwowania, myślenia i dostosowania się (nie należy mylić konsekwencji z wytrwałością).

Nie chodzi o to aby zafiksować się na czymś, spuścić głowę i konsekwentnie ryć niczym świnia za truflami. Co jakiś czas warto ją podnieść sprawdzić czy cel jest jeszcze wciąż na wprost - a może na horyzoncie pojawił się inny, lepszy cel i warto się zaadaptować?

wtorek, 25 maja 2010

Object Oriented czy jedynie Class Oriented?

Dziś będzie o "nowym" podejściu do Object Oriented.
Jeżeli komuś wydaje się, że już nic nowego nie można w tym jakże oklepanym temacie dodać, to zachęcam do zapoznania się prezentacjami zawartymi w tekście. Dowiecie się również dlaczego nowym napisałem w cudzysłowie.

Od jakiegoś czasu z wielu stron pojawiają się zachęty do zainteresowania się nowymi językami, takimi jak Scala, Groovy, Ruby,...

Do tej pory wszyscy orędownicy pokazują jak to fajnie można sobie operować na kolekcjach (sortować, wyszukiwać) w jednej linijce kodu dzięki możliwości "doklejania" nowych metod do istniejących klas. Z całym szacunkiem, ale jest to nic innego jak objaw onanizmu technicznego. Jeżeli mam zainteresować się nowym językiem tylko po to aby uniknąć klepania pętelek to jednak zastosuję "cwanego" utilsa. Czy aby na pewno nowe języki powstają tylko po to aby sobie dokleić do klasy String 100 nowych metodek, o których istnieniu wie tylko doklejający?

Jeszcze inni odkryli ponownie możliwość dynamicznego dodawania "w locie" do encji metod zapisujących i wczytujących je. Myślałem, że niesławny Active Record odszedł już dawno w niepamięć. Ale jednak nie - okazuje się, że jest sexi w niektórych frameworkach.

Podczas niedawnej sesji researchu trafiłem na ciekawą koncepcję, która nadaje prawdziwy i pragmatyczny sens tym wszystkim konstruktom językowym.Pojawił się oto "nowy" paradygmat programowania: Data Context Interaction, który wskazuje zastosowanie dynamicznych konstruktów do lepszego (a przynajmniej innego) modelowania problemów. Czyli mamy coś więcej niż sortowanie listy, mamy nową jakość myślenia o modelowanej strukturze.

Twórcy DCI twierdzą, że mainstreamowe podejście do OO to jedynie kilka % prawdziwego OO. Klasyczne podejście skupia się na klasach, czyli na pewnych strukturach. Stawiają oni klasycznemu podejściu zarzuty, że skupia się ono na klasach zamiast na obiektach, co jakoby powoduje "rozsmarowanie" logiki Use Case po wielu klasach, dzięki czemu w nietrywialnych aplikacjach z czasem coraz ciężej przychodzi połapanie się w logice.

Czy zatem czas na powrót do paradygmatu proceduralnego, gdzie mamy cały "flow" w 1 miejscu?
Niekoniecznie.
Spójrzmy ma poniższy rysunek:


źródło: http://www.underbjerg.com/2009/11/16/oredev-2009-impressions-and-dci-architecture/

Dane opisują przy pomocy Klas pewną niezmienną strukturę - można powiedzieć core modelu (może mieć on pewne bazowe, ogólne zachowania).
Interakcje są wyniesieniem zachowania do poziomu głównych bytów, dzięki czemu lepiej odpowiadają modelowi mentalnemu usera. Są pewnymi rolami, które mogą być przyjęte przez obiekty. Interakcje operują na Danych ponieważ są do nich mixowane w...
Kontekście - kontekst odpwiada Use Caseom lub ich krokom. To w pewnym kontekście dane są łączone z rolami (zachowaniem) tworząc dopiero obiekty.

Intuicyjny przykład: jestem człowiekiem, opisuje mnie zestaw standardowych parametrów. Ale w zależności od kontekstu przyjmuję niektóre role (a wraz z nimi zachowania): Programista, Manager, Ojciec, Kierowca, Gracz, Klient, ...


Jeżeli udało mi się chociaż trochę zainteresować Was koncepcją DCI (nie mylić z nieco mniej innowacyjnym CDI;) to polecam następujące materiały:

- Architektura i ciekawy przykład w Ruby - aby zaintrygować dodam, że znajdziecie tutaj ostrą krytykę TDD.
- Ciekawe podejście do modelowania - mamy tutaj przykład niesamowitej jasności myślenia i pokaz tragikomicznego frameworka Qi4j (Java się jednak nie nadaje do DCI)
- Niezbyt porywające wprowadzenie teoretyczne - z którego dowiemy się, że te koncepcje mają już kilkadziesiąt lat, tylko gdzieś się zapodziały w przemyśle.
- Niekoniecznie świadome DCI w Scali - plus durne przykłady sortowania kolekcji;)


Ogólnie polecam materiały z konferencji Øredev - jak widać tematyka jest jest bardzo ciekawa i mocno wykracza poza mainstream.

A w inkubatorze (póki co) Eclipse mamy coś bardzo podobnego: Object Teams


//==========================

Ciekawie DCI podsumował jeden ze znajomych architektów (przy okazji "snajper", który potrafi trafić człowieka z granatnika z odległości całej planszy w Modern Warfare 1): "ale trzeba mieć jaja aby zakwestionować standardy i przedstawić coś tak odmiennego".

niedziela, 9 maja 2010

Konstruktor-Destruktor

Stara indiańska zasada mówi: na blogu zawsze lepiej wkleić linka do czyjegoś mądrego posta niż pisać coś samemu. Dlatego dziś polecam posta Jakuba Nabrdalika: Writer versus Constructor. Tekst trafia w sedno pewnej klasy problemów z developmentem softu.

Od siebie dodam, że jak zwykle rzeczywistość nie jest czarno-biała lecz szara. Programista klasy MacGyver (o którym pisał Joel Spolsky) jest pożytecznym skarbem w zespole, trzeba jedynie objąć go stałą kwarantanną.


EDIT:
Kontynuacja dyskusji: O programiście-pisarzu i programiście-konstruktorze, ciąg dalszy czyli: refaktoring po blogersku?

//=======================

Przy okazji warto zwrócić uwagę nad konstrukcję samego posta - wzór do naśladowania dla wszystkich bloggerów technicznych.

Najpierw mamy krótką historię odwołującą się emocji (w tym wypadku z dzieciństwa), później uogólnienie i postawienie problemu. Dalej w rozwinięciu wypunktowanie konkretów. Wszystko ilustrowane perfekcyjnie dobranymi, klimatycznymi obrazkami Pipboya z Fallouta.

Brawo, brawo, brawo!

środa, 28 kwietnia 2010

Majowa ewangelizacja Software Craftsmanship


Prezentacja poświęcona tematyce Software Craftsmanship została dosyć ciepło przyjęta podczas poznańskiego 4Developers, oraz spotkała się z niemałym odzewem w community.

Dlatego uznałem, że warto kontynuować propagowanie profesji w naszej branży - szczególnie, że nasze community zaczyna coraz wyraźniej sygnalizować pewne problemy.

Zapraszam zatem wszystkich zainteresowanych tematyką Software Craftsmanship na szereg darmowych konferencji, gdzie planuję wystąpienie:

- lubelskie dni IT - 12 maja w Lublinie
- Infoshare - 14 maja w Gdańsku
- Javarsovia - 26 czerwca w Warszawie

//==================================

Cieszy fakt, ze tematyka Craftsmanship pojawia się również na JUGach: warszawskim i wrocławskim

środa, 21 kwietnia 2010

Google Application Engine



Dziś będzie o rzetelności.

WYGLĄDA OBIECUJĄCO

Chmura Google - GAE ogólnie prezentuje się świetnie. Za darmo (do pewnych limitów) dostajemy platformę, która jest w stanie udźwignąć tysiące transakcji na sekundę oraz przechować dla nas terabajty danych w nierelacyjnej bazie BigTable. Do tego dostęp do wielu usług google takich jak bezpieczeństwo, składowanie obrazków, pobieranie zawartości stron poprzez ichni cache, potężny memcache itp.

Programować możemy sobie w Pythonie albo w Javie (okrojonej wersji, bez części klas standardowych i z zakazem korzystania z pewnych bibliotek).

Ogólne założenie jest takie: programiści (i konsultanci;) w większości nie potrafią konfigurować skalowalnych środowisk ani pisać skalowalnych aplikacji, dlatego dostarczmy im platformę, która zajmie się tym problemem w sposób transparentny. Czyli mamy podejście odwrotne do Java EE. Zajmij się problemem biznesowym a chmura zajmie się skalowaniem. Kierunek wydaje się słuszny.

Zatem zaczynamy zabawę...
Na dzień dobry krótka, oficjalna prezentacja z głównej strony jak to fajnie i szybko klepie się aplikacje i odpala je w kosmos: http://www.youtube.com/watch?v=P3GT4-m_6RQ
Trzeba przyznać, że plugin do Eclipse jest wzorowy: prosty w obsłudze (3 sugestywne buttony), działa oraz zapewnia wszystko:
- lokalny server emulujący chmurę i jej zasoby (bazę)
- narzędzie automatycznie "wzbogacające" bytecode klas encji na potrzeby ichniej "implementacji" JPA
- narzędzie wystrzeliwujące aplikację w kosmos
- prosty kreator, który generuje cały ten kosmodrom
(nie odważyłem się zmawenizować wygenerowanego projektu, bo to zwykle tydzień w plecy a na koniec może się okazać, że tracimy hotdeploy)



WTF?

Ale, ale... akcja filmu rozkręca się z czasem...
Jedna z największych firm programistycznych na ziemi pokazuje jak tworzyć kod w... Java Server Pages. Patrzcie uważnie i uczcie się: logika i dostęp do danych w... scriptletach (sic!).

Oczywiście duzi chłopcy wiedzą, ze scriptlety są depricated. A nóż widelec tą scenę zobaczy jakieś małe dziecko i będzie później tak programować jak dorośnie?!? Później znowu przeczytamy w gazecie o tragedii jaka rozegrała się w jakimś spokojnym projekcie. Gdzie byli rodzice?!?

Hmmm dziwne, dziwne... no ale nie czepiajmy się szczegółów, to przecież tylko taki przykład. Przecież zawsze możemy zaprojektować sobie eleganckie warstwy i całość oprzeć o sprawdzony framework.



BOLESNE OGRANICZENIA

Niestety tak jak wspomniałem na początku JVM ma ograniczenia i nie wszystko działa. Seam co prawda daje się uruchomić po zastosowaniu 15 speszyl haków, ale wszyscy twierdzą, że nie warto ryzykować. Na szczęście stary, dobry Spring oficjalnie działa. Wielu dzielnych blogerów publikuje hello worldy i tutoriale jak to poskładać. Wygląda na to, że jedni kopiują od drugich;)

Ba, nawet 2 książki o GAE preferują Springa i pokazują jak go skonfigurować. Hmmm ciekawe dlaczego omawiają tylko servlecik Spring MVC i dyplomatycznie nie poruszają bardziej zaawansowanych zagdanień...?

Niestety, jednak nie działa do końca!
Przykładowo gdy użyjemy technik Aspektowych i przeplatania w czasie uruchomienia to mamy dziwne błędy ClassNotFound. Lokalnie działa, a na chmurze już nie.
Co implikuje, że możemy zapomnieć o aspektowej, eleganckiej obsłudze bezpieczeństwa i transakcji.
Więc po co nam Spring? Tylko do wstrzykiwania? To bez sensu.



UWAGA NA PERSYSTENCJĘ

Nieważne, bez Springa można żyć, idźmy dalej... Nierelacyjna baza BigTable została przez Google przykryta interfejsem JDO albo JPA (do wyboru) więc czujemy się jak w domu.
Nie do końca... specyfikacja ma szereg ograniczeń wynikających z architektury rozwiązania BigTable - chodzi o rozpraszanie struktur danych na różne maszyny po stronie chmury.

Drobny szczególik wspomniany jedynie w dokumentacji jest taki, ze agregaty encji są grupowane w rodziny. Przykładowo jeżeli mamy encję Zamówienie, która ma w sobie listę ZamówionychProduktów to jest to rodzina. Co z tego wynika?

Encja może należeć jedynie do jednej rodziny.
Implikacja: Jeżeli mamy encje Zamówienie i Faktura oraz encję Kleint, który musi być podpięty do Zamówienia jak i Faktury to niestety nie ma takiej możliwości. Dziecko może mieć jednego rodzica. Oczywiście można to obejść i w Zamówieniu jak i Fakturze używać obiektów Kluczy do Klienta. Ale wówczas tracimy łatwość programowania i uzależniamy się od API Chmury.

Trzeba pamiętać, że podejście do modelowania danych w nierelacyjnej bazie wymaga innego "nastawienia" - taka natura rozwiązania. Jeżeli nierelacyjnie to może obiektowo? Jednak nie do końca - no to jak?

Osobiście preferuję takie podejście, że Zamówienie czy Faktura ma owszem klucz do Klienta ale ma również niepersystentne pole Klient, które jest ustawiane w niej osobnym zapytaniem (nie jest to duży koszt w bazie BigTable, która jest tak na prawdę wielowymiarową HashMapą). Tego typu szczegóły można hermetyzować z obiektach Repository, które zwracają dane "poskładane" tak aby było wygodnie. OK, jeden problem z głowy.


Transakcja może obejmować tylko operacje na jednej rodzinie.
Czyli jeżeli logika aplikacji chce zapisać zarówno rodzinkę Zamówienie jak i Faktura to będą to 2 osobne transakcje. A co jeżeli w tak zwanym międzyczasie zdarzy się coś przykrego? Ręczna rzeźba i sprzątanie:)
Poza tym, jak wspomniałem, aspektowe transakcje Springa nie działają, więc brudzimy kod biznesowy kodem API transakcji JPA.


Datanucleus - "implementacja" JPA
Oprócz tego, że jest okrojona to dodatkowo zawiera szereg błędów - nie działają nawet niektóre proste przykłady z tutoriali JPA. Na oficjalnej grupie wisi wiele pytań - bez odpowiedzi.



GWÓŹDŹ

Prezentacja
Z frameworków prezentacji testowałem JSF.
1.2 (z Seam) działa.
2.0 działa po zastosowaniu jednego prostego speszyl haka.

Działa w sensie, że się uruchamia. W 2.0 występują pewne problemy z wstrzykiwaniem ManagedBeanów. RichFaces ani IceFaces nie mają wersji dla chmury. Oficjalnie Primefaces częściowo działa. Znowu nie jest to rzetelna i informacja - AJAX ogólnie się sypie.

No i można zapomnieć o uruchamianiu metod z parametrem przy pomocy nowego silnika wyrażeń (el-api w wersji 2.2). Chmura odmawia współpracy z nowymi zdobyczami.

//==============================

Biorąc pod uwagę powyższe ograniczenia:
- brak wygodnego frameworka (w tym wsparcia dla AOP)
- uboga funkcjonalność ORM wymagająca wielu ręcznych operacji
- mentalny model programowania sprzed o ok 10 lat
Mamy znaczny spadek produktywności.

Domyślamy się skąd te JSP, scriptlety i statyczne metody w filmie promocyjnym? Czyżby tylko to działało?
Szkoda tylko, że community i blogosfera zatrzymuje się na poziomie Hello World i nie weryfikuje nieco bardziej dogłębnie i rzetelnie.

Na zakończenie dodam, że zupełnie inne założenia przy budowie chmury przyjął Amazon. Dostajemy sprzęt i system operacyjny. Nikt nie narzuca nam dodatkowych bytów zbudowanych nad sprzętem i nie wchodzi nam z butami w nasz wypracowany latami i sprawdzony model programowania. I co najważniejsze - wszystko działa:)

wtorek, 23 marca 2010

Koszt wykorzystania wzorców projektowych

Podczas dzisiejszej prezentacji na temat Software Craftsmanship i Wzorców Projektowych, którą przeprowadziłem w ramach lubelskiego JUG padło szereg pytań odnośnie:
- kosztu posługiwania się w kodzie wzorcami
- presji czasu
- komplikacji

Jest to pewien ogólny i często powtarzający się zestaw pytań, dlatego sądzę, że warto rozwiać kilka wątpliwości i nieporozumień.

Część programistów widzi wykorzystanie wzorca jako niepotrzebną komplikację, która wprowadza dodatkowy narzut na wytworzenie kodu.

Generalnie jeżeli chodzi o poziom komplikacji to wzorce powinny redukować złożoność przypadkową oraz zwiększać czytelność złożoności właściwej. Jeżeli mamy sytuację odwrotną to wzorzec został wykorzystany niepoprawnie lub niepotrzebnie.

Odnośnie narzutu czasowego to obserwuję dziwne przeświadczenie jakoby dopisanie interfejsu czy kilku linijek kodu potrzebnych na podzielenie kodu na większą ilość pudełek (klas) było jakoś niezwykle czasochłonne;) Sam proces myślowy również nie powinien się znacząco wydłużyć. Albo wiem jaki wzorzec użyć albo nie wiem. To nie jest tak, że zastanawiam się nad tym godzinami.

Warto zwrócić uwagę na fakt, że katalog Wzorców Projektowych Ogólnego Przeznaczenia jest dosyć bogaty.

Owszem, część z nich jest dosyć wyrafinowana pod względem koncepcyjnym lub pod względem konstrukcji kodu. Przykładowo taki Visitor, Component Tree, Bridge, Proxy, Builder, Flyweight, Memento prowadzają pewien narzut, ale są to narzędzia, które wybieramy do misji specjalnych. Na pewno nie należą do codziennego wachlarza technik.

Natomiast Strategia, Stan, Dekorator, Template Method, Command to lekkie "skróty myślowe" wynikające wprost w paradygmatu Object Oriented. Nie ma w nich doprawdy nic nadzwyczajnego.

Osobiście traktuję część z nich jako "atomowe klocki", z których powinno budować się rozwiązania. Są to byty niemal tej samej klasy ciężaru co IFy, pętele czy metody. Biegłe opanowanie lekkich wzorców sprawia, że poszerzają one nasz zestaw podstawowych "klocków myślowych". Budujemy z nich najpierw mentalne modele, a później naturalnie pojawiają się w kodzie.

Operując lekkimi wzorcami na poziomie podstawowych klocków nie mamy narzutu czasowego podczas developmentu. Natomiast poziom komplikacji ulega znacznemu obniżeniu, ale tylko dla tych czytelników kodu, który posiadają taki sam zasób skojarzeń jak jego twórca - czyli operują tym samym słownictwem branżowym.

//=====================================

Potrzeba posiłkowania się wzorcami "lekkiego" kalibru wynika ze słabej siły wyrazu języków wywodzących się z C++ takich jak np Java. Przykładowo brak domknięć kompensujemy sobie strategiami. Doprawdy nie jest niczym strasznym i pracochłonnym opracowanie interfejsu z jedną metodą oraz kilku jej implementacji. Ilość kodu "biznesowego" nie ulega zwiększeniu (ew redukcji) natomiast pojawiają się jedynie dodatkowe "opakowania" dla niego w postaci zgrabnych i eleganckich klas.

Jeżeli ktoś aż tak bardzo nie pała chęcią do pisania kodu to może powinien zostać trubadurem;)

Ciężki kaliber wzorców również może czasem przydać się do emulacji brakujących elementów składni, takich jak:
- double dispatch emulowany przez wzorzec Visitor
- lazy evaluation emulowany przez wzorzec Proxy.

wtorek, 9 marca 2010

Wyginanie Javy



Dzisiejsza prezentacja Wojtka Gomoła o wyrażeniach Lambda (C# i "emulacja" w Javie) na Lubelskim JUG przypomniała mi o kilku ciekawych zabawkach, które jakiś czas temu znalazłem i zapomniałem o nich napisać.

Ciekawą cechą dynamicznych języków funkcyjnych jest:
- możliwość tworzenia konstrukcji zbliżonych do języka naturalnego
- możliwość rozszerzania standardowych, często używanych klas (zwykle kolekcji, kontenerów) o wygodne metody
- nazwijmy to w sumie roboczo "techniczny DSL"

Przykładowo takie oto sprawiające radość uproszczenia:

kolekcja.wyrzucZNullemWPolu("name").posortuj({e1.age >e2.age}).wytnijPierwszych(10);


Jak dla mnie nie ma się czym ekscytować ponieważ jest to jedynie lukier składniowy i w statycznych językach z silną kontrolą typów jest to tylko kwestia stworzenia jakiegoś starego, dobrego, proceduralnego Utilsa z interfejsem strategii komparacji:

MyAlmightyUtils28.wyrzucZNullemWPolu(kolekcja, "name")

oraz odpowiednia sekwencja wywołań.

/*Oczywiście wszyscy wiemy, że Utilsy są złe i brzydkie, ale co zrobić*/

No ale już nie będzie tak pięknie jak we wcześniejszym przykładzie z jakiegoś sexi-skryptowego-języka.


Na szczęście istnieje kilka ciekawych zabawek zaimplementowanych w Javie. Dzięki cwanym trikom na generykach i zastosowaniu odpowiedniego nazewnictwa dają nam coś więcej niż namiastkę konstrukcji znanych z dynamicznych, słabo otypowanych języków.

op4j - genialna biblioteka, która sprawia, że żmudny kod staje się bardziej czytelny i zwięzły jednocześnie zachowując typowanie.
Bardzo podstawowy przykład:

String[] emailArray = Op.on(userEmails).toArrayOf(Types.STRING).forEach().exec(FnString.toLowerCase()).get();


lambdaj - podobna zabawka ze stajni google. Można rzucić okiem również na google collections.

Mockito - nasza rodzima produkcja. Kto jeszcze nie używał, ten powinien spróbować. Warto zajrzeć choćby do kodu ponieważ stanowi on przykład wzorcowej dokumentacji. Cały manual wraz z przykładami znajduje się w JavaDocu głównej "klaski"! Wzór do naśladowania dla innych twórców bibliotek - bo na pewno nie dla developerów komercyjnych produktów;)

//==================

Czekamy na Javę 1.7 z jej nową konstrukcję closures. Ale forma w jakiej pojawi się ona w nowym wydaniu języka będzie praktycznie niczym innym niż uproszczonym wydaniem anonimowej klasy wewnętrznej. Czyżby ukłon w stronę tych hakerów, którzy nie mogą połapać się w konstrukcji anonimowych klas albo Wzorca Strategii?

No i na pewno na certyfikatach pojawią się kolejne arcyistotne pytania mające na celu sprawdzenie czy delikwent jest w stanie odróżnić: domknięcie od klasy wewnętrznej i od niekompilującego się kodu;P

niedziela, 7 lutego 2010

Inżynieria w służbie użyteczności

/*
 *Tytuł niczym wzięty ze sztandaru
 *z jakiegoś pochodu
 *z uprzedniej smutnej epoki:)
 */

Witam po długiej przerwie. Zaprezentuję dziś pewne ujęcie Usability oraz koncepcję technicznego rozwiązania użytecznej aplikacji - jej architekturę i dwa główne wzorce projektowe.

NOWICJUSZ vs EKSPERT
Użyteczność niejedno ma oblicze. Możemy mówić o przejrzystości, intuicyjności, ergonomii itd. Każdy z nas zapewne zdefiniuje dobre GUI jako takie, które oferuje to czego się spodziewamy. Ale co to znaczy? Oczywiście dla każdego coś innego.

Dziś skupimy się na problemie różnych potrzeb i oczekiwań użytkowników o różnym poziomie zaawansowania.

Analizując Model Rozwoju Kompetencji Braci Dreyfus
krótki opis
szerszy opis
możemy wywnioskować, że użytkownicy reprezentujący skrajne poziomy kompetencji potrzebują skrajnie odmiennego GUI.

Nowicjusz i Zaawansowany Początkujący są nastawieni na zadania ponieważ nie ogarniają jeszcze całości problemu. Potrzebują określonej ścieżki, przez którą będą prowadzeni za rękę a na każdym etapie dostaną jasne wytyczne odnośnie tego CO trzeba zrobić.

Z drugiej zaś strony Kompetentny, Biegły i Ekspert są nastawieni na osiągnięcie celu i mniej lub bardziej orientują się jak go osiągnąć.

Jak to w życiu bywa: "różni ludzie, różne potrzeby".

Mniej zaawansowani użytkownicy potrzebują aplikacji-asystenta zorientowanej na zadania. Aplikacja taka nie powinna atakować mnogością możliwości. Powinna w danym momencie sugerować (lub wręcz zmuszać) do zrobienia właściwej rzeczy. Przykładem mogą być nasze ulubione kretynatory (yyy kreatory).

Zaawansowany użytkownik potrzebuje aplikacji zorientowanej na możliwości. Dla niego wygodne będzie rozbudowane menu, bez sugerowania co kiedy kliknąć. Zaawansowany użytkownik dobrze wie co chce zrobić i nie potrzebuje aby mu podpowiadać. Mało tego, taki użytkownik ma wyrobiony swój własny styl pracy, zatem aplikacja-asystent jedynie przeszkadza. Najlepszym przykładem może być: IDE (np. Eclipse), zaawansowany edytor tekstu albo narzędzie typu CAD. Tysiące opcji w menu i biała kartka na dzień dobry.


Klasyczny problem występujący w aplikacjach biznesowych to nauka obsługi użytkowników. Stare systemy tej klasy orientowało się na możliwości (teraz powoli sytuacja ulega zmianie). Mamy zatem nieszczęsną użytkowniczkę, która zaczyna naukę obsługi systemu (może również jednocześnie "uczy się komputera"). Przytłoczenie mnogością opcji skutkuje jednym: tresurą. Użytkownik nie ma innego wyjścia jak opanowanie procesu biznesowego na zasadzie szympansa: klikam trzeci z lewej, później ok, później przedostatnia zakładka, później klikam drugi od dołu...

Wszyscy znamy też nietrafione rozwiązanie, które miało pomagać nowicjuszom w okiełzaniu eksperckiego narzędzia - spinacz w Office;)

PRZYKŁAD APLIKACJI
W przypadku aplikacji korporacyjnych jest łatwiej. Użytkownik nie ma innego wyjścia jak zacisnąć zęby i nauczyć się (pardon - wytresować się). Jest to po prostu przykre narzędzie jego pracy.

Natomiast gdy nasza aplikacja ma konkurować na wolnym rynku wówczas musimy nieco się wysilić. Użytkownik zirytowany autystycznym GUI aplikacji po prostu porzuci ją, zaklnie i pójdzie sobie do konkurencji:)

Użytkownicy są teraz niezbyt cierpliwi i mają wysokie wymagania odnośnie przyjemności - pokolenie MTV?


Aby ustalić kontekst aplikacji walczącej o klienta wysokim poziomem użyteczności wyobraźmy sobie system do projektowania wnętrz, np. wnętrz kuchni.
Niech zaprojektowanie wymaga między innymi: określenia obszaru pomieszczenia, ustalenia otworów i innych przeszkód, rozstawienia mebli i AGD, dopasowania wszystkich wymiarów, wyboru materiałów z których mają być wykonanie poszczególne elementy, itd. Dalej mamy rysunki techniczne, wyliczenia należności, umowy, itp.

Ustalmy wyzwanie: z aplikacji ma być wykorzystywana przez:
- klientów końcowych, którzy to raz na kilka(naście) lat kupują sobie "kuchnię"
- projektantów kuchni, którzy dziennie wyklikują po kilka takich zestawów.

Co z kompetencjami naszych użytkowników?
Jasne jest, że klient końcowy jest totalnym Nowicjuszem jeżeli chodzi o aplikację. Użyje jej raz (ew jako rodzinny "haker" pomoże szwagrowi wyklikać jego zestaw). Zatem nigdy nie nabędzie wyższych kompetencji. Co gorsza klient może być również niekompetentny w domenie problemu, czyli wszystkich zagadnieniach związanych z kuchniami.
Manual oczywiście odpada, bo zirytowany klient pójdzie sobie do konkurencji.

Projektant jest zwykle w miarę kompetentny w domenie problemu;) Będzie też Nowicjuszem jako użytkownik, ale ponieważ będzie miał motywację i częstą styczność z aplikacją to szybko osiągnie poziom Kompetentny a z czasem dojdzie do Eksperta.

ARCHITEKTURA ROZWIĄZANIA
Mamy zatem dwie klasy użytkowników, którzy potrzebują diametralnie różnego interfejsu. Początkujący użytkownik wymaga przeprowadzenia go przez cały proces projektowania krok po kroku, bez zbędnych pytań, defalutowo, szybko, gładko i bez irytacji. Zaawansowany użytkownik potrzebuje natomiast wolności, możliwości i tysięcy szczegółowych opcji.

Jak to pogodzić? Czy musimy tworzyć niemal 2 osobne aplikacje?
Niekoniecznie, jeżeli podejdziemy do problemu racjonalnie to możemy zredukować narzut związany z przygotowaniem 2 wersji.

Możemy podejść do problemu następująco:

Wydzielamy CORE aplikacji, który zawiera klasy odpowiedzialne za główną funkcjonalność, czyli projektowanie wnętrz (wraz ze wszystkimi regułami z tym związanymi) oraz wizualizację projektu.
Core jest dostępny przez API.

Mamy 2 zestawy GUI: jeden prosty i intuicyjny oraz zorientowany na zadania przeznaczony dla początkujących. Drugi to klasyczny potwór dla eksperta oferujący niezliczone możliwości w rozbudowanych menu.

Oba rodzaje GUI komunikują cię z Corem wysyłając polecenia zhermetyzowane przy użyciu wzorca projektowego Command. Idea wzorca jest taka, że czynności nie są metodami (jak w klasycznym podejściu proceduralnym). Czynności są obiektami. Dla wszystkich klas poleceń istnieje wspólny interfejs zawierający jedną metodę - jest to sygnał do polecenia aby wykonało ono zawartą w sobie logikę.

Konkretny command zawiera w sobie zestaw instrukcji operujących na API Cora. Oczywiście commandy wysyłane z GUI Nowicjusza będą zawierać więcej kodu operującego na API. Jedna czynność takiego użytkownika wykonuje więcej operacji. Commandy wysyłane z GUI Eksperta będą bardziej elementarne. Commandy mogą po sobie dziedziczyć, mogą się na wzajem dekorować z wykorzystaniem wzorca Dekratora w celu reużycia logiki.

W przedstawionej architekturze mamy dodatkowo wzorzec Mediatora. Został on wprowadzony jako "środowisko uruchomieniowe" dla poleceń oraz "hub" spinający wiele komponentów. GUI wysyła commadny do Mediatora, a to mediator wykonuje otrzymane polecenie (uruchamiając wspólną metodę interfejsu) przekazując do nich kontekst uruchomienia, czyli core.
Mediator może również przy okazji manipulować stanem GUI, które nie należy do Core (np nakładać przeźroczystą chmurę na czas długotrwałych operacji bądź włączać dostępność opcji w menu). Mediator może też generować zdarzenia aplikacyjne, które będą obsługiwane przez pewne komponenty graficzne prezentujące zajście danego zdarzenia. Można bawić się do woli z Mediatorem, ale trzeba uważać aby nie stał się boską klasą o zbyt dużej odpowiedzialności.

ZWIĘKSZAMY USABILITY
Każdy użyteczny system, którego idea zasadzą się na bogatej interakcji użytkownika powinien oferować funkcjonalność "Cofnij". Wprowadzenie tej funkcjonalności jest generalnie bardzo kłopotliwe. Kto zmagał się z tym problemem ten zapewne próbował niewydajnego rozwiązania polegającego na "zrzucie" aktualnego stanu do pamięci podczas wykonywania każdej operacji modyfikującej stan.

Ogólnie jest to problematyczna funkcjonalność, chyba że...


...posiłkujemy się wzorcem Command:)

Możemy wówczas rozszerzyć go o anti-command.
Każde polecenie zawierające logikę zawiera w sobie anty polecenie (jako obiekt dostępny przez getter - a getter w interfejsie Command). Antypolecenie zawiera logikę odwrotną do polecenie.

Teraz w naszym przypadku Mediator wykonując polecenie, pobiera z niego anty-polecenie i odkłada je na stosie. W razie potrzeby, czyli gdy użytkownik kliknie cofnij (ctrl+z) wołamy Mediatora, który pobierze polecenie ze stosu anty-poleceń i wykonana go. Proste:)


//==============================

O ile omawiana problematyka usability w kontekście kompetencji użytkownika jest ogólna, to przedstawione rozwiązanie nie aplikuje się do aplikacji webowych z cienkim klientem. Zresztą taki klient ma zastosowanie do innej klasy problemów.

Natomiast rosnąca popularność grubszych klientów (opartych o: flex, javafx, silverligh, stare-dobre-niedoinwestowane-przez-matołów-suna applety czy nawet GWT) pozwala przewidywać, że coraz częściej będziemy spotykać się problemami tej klasy.

wtorek, 26 stycznia 2010

Wspinaczka do profesjonalizmu

Wreszcie po ponad miesięcznej przerwie znalazłem chwilę czasu na napisanie posta:)
Brak czasu na pisanie wynika głównie z nawału nowych obowiązków związanych z opieką nad 3-tygodniową córką:]

Dlatego też dziś odsyłam do artykułu mojego autorstwa, który ukazał się w lutowym wydaniu SDJ pt:
"Wspinaczka do profesjonalizmu
Modelowa ścieżka rozwoju kompetencji – podejście pragmatyczne"


Artykuł traktuje o rozwoju kompetencji developerskich w kontekście Modelu Kompetencji Braci Dreyfus, o którym już pisałem.

W tekście zachowano znaczniki specyficzne dla wydawnictwa, ponieważ są czytelne dla "ludzi z branży" a jednocześnie nadają mu strukturę. Tekst zawiera kilkanaście stron, ale podobno szybko i lekko się go czyta;)

Zapraszam do lektury artykułu i być może nawet całego numeru poświęconego programowaniu gier - zawsze to ciekawa odmiana od enterprajz;)

//========================

W ciągu najbliższego tygodnia noworodek powinien przepoczwarzyć się w mniej zasobożerne niemowlę a co za tym idzie pojawi się kilka nowych postów. Będą poświęcone zagadnieniom z zakresu Craftsmanship, m. in. projektowaniu systemu pod kątem usability (na podstawie moich ostatnich doświadczeń z paroma autystycznymi koszmarkami) .