niedziela, 16 grudnia 2012

Testowanie automatyczne - artykuł

W najnowszym numerze programistamag.pl ukazał się kolejny artykuł z serii DDD: "Kompendium testowania aplikacji opartej o DDD – problemy, strategie, taktyki i techniki".

Artykuł można pobrać również tutaj: http://bottega.com.pl/artykuly-i-prezentacje (całkowicie free:).

Problem testowania automatycznego został osadzony w kontekście DDD, ale traktuje o testowaniu w ogólności, tak więc lektura powinna być pożyteczna dla każdego programisty i projektanta. Proponujemy w nim nieco inne spojrzenie na klasyczną już piramidę testów - dosłowne mapowanie piramidy na architekturę warstwową oraz nieco inne spojrzenie na pokrycie kodu testami.

Treść została uporządkowana wg struktury: Problemy, Strategie, Techniki, Taktyki i Narzędzia.
Jest to autorska metodyka opracowana w naszej firmie, którą stosujemy podczas coachingu z zakresu testowania automatycznego, składająca się z 2 etapów:
  • W fazie analizy sytuacji poruszamy się ścieżką top-down aby zdiagnozować cele na każdym poziomie w kontekście poziomu wyższego.
  • Natomiast w fazie wdrażania (coachingu) poruszamy się ścieżka bottom-up aby skupić się tylko na tych aspektach, które wprowadzają największą wartość.
Jeżeli wdrażasz (lub planujesz wdrożyć) zmiany we własnej organizacji to zachęcamy do wypróbowania tego podejścia i podzielenia się spostrzeżeniami.

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

Jednak główne przesłanie artykułu to: "unikaj pracy z serwerem aplikacji i bazy danych". Ile czasu zajmuje Ci cykl od momentu wciśnięcia ctrl+s w swoim IDE do przekonania się czy zmiany w kodzie są poprawne? Kilkanaście minut? Próba hotdeploymentu, przeładowanie aplikacji, które kończy się restartem serwera, przygotowanie danych, przeklikanie kilkunastu formularzy (każdy po kilka zakładek z kilkunstaoma polami) aby wreszcie zobaczyć np złą kwotę po naciśnięci "Zatwierdź" na ostatnim formularzu.

Czy po to studiowałeś/studiowałaś 5 lat?

Dzięki wydzieleniu warstwy domenowej, a w niej posługiwaniu się Bulding Blocks zgodnie z zasadami DDD osiągamy wysokie testability kodu, które pozwala na pracę z pojedynczymi fragmentami modelu przy pomocy testów jednostkowych (tanich w stworzeniu, bo unikamy sytuacji gdy potrzeba stworzyć Mock/Stub/Fake).







niedziela, 2 grudnia 2012

Java User Group - Wrocław, Szczecin, Kraków

Entuzjastów inżynierii oprogramowania (niekoniecznie związanych z Javą), zapraszam na 3 prezentacje, które odbędą się w ramach lokalnych JUGów (wstęp wolny również dla uczestników spoza JUG)

Wrocław 4 grudnia:
Tematy: Techniki strukturyzacji architektury oraz rozwinięcie do Architektury Ports & Adapters.
Szczegóły pojawią się na stronie grupy.

Szczecin 10 grudnia:
Tematy: Techniki strukturyzacji architektury oraz rozwinięcie do Architektury Ports & Adapters.
Szczegóły pojawią się na stronie grupy.

Kraków 13 grudnia:
Temat i miejsce ustalamy na grupie dyskusyjnej Polish JUG. Więcej info pojawi się gdy ustalimy szczegóły.

niedziela, 11 listopada 2012

DDD krok po proku - dostęp do artykułów i plany kolejnej serii

Ostatnie pół roku działalności bloga można podsumować krótko: marazm:)

Przyczyną jest oczywiście nawał pracy. Miesięczny "zasób weny" inwestowałem w projekt tworzenia serii artykułów "DDD krok po kroku", która ma na celu przedstawienie technik z zakresu architektury systemu, architektury aplikacji oraz implementacji projektu opartego na podejściu DDD.

Artykuły są publikowane co miesiąc w  programistamag.pl, natomiast dzisiaj - dzięki uprzejmości redakcji - możemy je udostępnić w formie niekomercyjnej - do pobrania tutaj.

W serii zaplanowane są jeszcze 2 artykuły:
  • Kompendium testowania automatycznego - problemy, strategie, taktyki i techniki
  • Kompleksowy proces modelowania DDD "Modeling Whirlpool" (z elementami BDD i Specification by Example)

Oba artykuły zostaną również udostępnione na blogu i będą ekstraktem całej naszej aktualnej firmowej wiedzy, którą stosujemy w projektach i pracy coachingowej z zespołami.

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

W planach mam kolejną serię artykułów, tym razem przeznaczoną dla początkujących programujących projektantów i programujących architektów. Seria będzie miała na celu wprowadzenie początkujących w świat podstawowych pojęć jak również zaawansowanych koncepcji oraz konkretnych rozwiązań typowych problemów.

Tematy z założenia nie będą ze sobą powiązane, jednak chciałbym wprowadzać bazowe pojęcia w początkowych artykułach aby na ich bazie budować bardziej złożone struktury.

Przykładowe tematy:
  • Trzy smaki odwracania (i utraty) kontroli 
  • Programowanie funkcyjne w Javie - kiedy i po co?
  • Fabryka dekorowanych strategii - czyli o trójpodziale logiki
  • Deus ex Machina Stanów - dlaczego potrzebujesz jej w modelu biznesowym i jak zrobić ją źle 
  • Lazy Loading w pułapce czasu - błędy logiczne, które prawdopodobnie masz i o których prawdopodobnie nie wiesz
  • Emulacja Traits w Javie - Role Object Pattern
  • Mock czy Stub? - Command-query Separation prawdę Ci powie
Jeżeli ktoś chciałby "zamówić" jakiś temat to czekam na propozycje.

czwartek, 1 listopada 2012

A teraz coś z zupełnie innej beczki: Mózg

Długi jesienny weekend może być okazją do refleksji, tak więc chciałem zaproponować temat. Temat poniekąd branżowy, jednak nie związany z systemami klasy Enterprise tudzież robieniem "internetów", nie związany z metodykami ani dywagacjami nad tym, który język "wąsaty" (wywodzący się z C++) jest słabszy ani z tym który framework przeszkadza bardziej lub czy testy lepiej pisać przed czy po:)

Temat pozwalający oderwać się od klas problemów z jakimi zmagamy się na co dzień (np. praca nad tym aby czyjś biznes działał lepiej) i nabrać do nich nieco dystansu...

Na podstawie rozmów ze znajomymi postawię tezę, że niemal każdy kto zetkną się na studiach z tematyką Sztucznych Sieci Neuronowych był nią zauroczony. Wyjątkiem mogą być nieszczęśnicy, którzy trafili na inwalidę pedagogicznego, który skutecznie tematykę obrzydził - ale pomińmy smutne wyjątki.

Jeżeli zaliczasz się do grona zauroczonych, to polecam prezentację Jeffa Hawkinsa Computing Like the Brain. Jej tytuł jest przewrotny, bo już na wstępie dowiecie się, że wg najnowszej wiedzy mózg nie jest "maszyną wykonującą obliczenia" a "jedynie" pamięcią. I to bardzo sprytną pamięcią o ciekawej charakterystyce. W dalszej części dowiecie się, że generalnie "szkolne" SSN jedynie w nazwie używają metafory sieci neuronowej, natomiast z mózgiem nie mają nic wspólnego.

Po wchłonięciu wiedzy z prezentacji zachęcam do refleksji nad: paradygmatami programowania (czy wszystko jest na pewno obiektem/funkcją?) nad paradygmatami modeli danych (sql/nosql),... Ciekawe jak nasze mózgi przyswoiły sobie paradygmaty, które są zupełnie inne niż ich wewnętrzna implementacja:P

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

Sam Jeff Hawkins sam w sobie jest postacią inspirującą.

Z noty biograficznej zawartej w jego książce On Intelligence dowiedziałem się, że jako student został owładnięty rządzą zrozumienia jak działa mózg.

Jego pomysły zostały wyśmiane w kilku korporacjach, co zatem zrobił? Przez kilkanaście lat zbudował kilka biznesów niezwiązanych z mózgiem, które przynoszą mu niezłe dochody. Jeff jest na przykład człowiekiem, który opatentował algorytm rozpoznawania pisma odręcznego - prawdopodobnie używasz go na co dzień.

Po kilkunastu latach powrócił do swej pasji wyposażony w wiedzę i kapitał, który sam sobie zdobył na ten cel. Jedne z jego firm wypracowują dochód, który inwestuje w inne swe firmy prowadzące przełomowe badania nad mózgiem. Na początku z czystej ciekawości (niektórzy na prawdę tak mają), natomiast aktualnie jego rozwiązania wygrywają wyścigi tradingowe z innymi automatami. Epic Win!

niedziela, 14 października 2012

Kalendarz na październik

Informacja dla entuzjastów inżynierii oprogramowania o nadchodzących wydarzeniach (które współorganizujemy):

Niekomercyjne:

- Warsjawa - 27.10.2012 warsztaty z zakresu Specification by Example oraz Behavior Driven Development

Podczas warsztatów będziemy demonstrować 2 uzupełniające się podejścia do modelowania wymagań: Behavior Driven Developemnt oraz Specification by Example. Dodatkowo nawiążemy do wynikającego z nich modelowania domeny z wykorzystaniem Building Blocks DDD. Przedstawimy również własne podejście do strategicznego testowania: mapowania rodzajów testów na warstwy aplikacji.

Od strony warsztatowej będziemy pracować nad 3-poziomowymi wykonywalnymi specyfikacjami:
3. Wykonywalne specyfikacje (cele biznesowe)
2. Wykonywalny flow (np. User Story)
1. Automatyzacja interakcji z systemem (abstrakcja nad ciężkimi w utrzymaniu skryptami testowymi: Agenty oparte na Selenium i Spring Remoting)

Podczas warsztatów będziemy pracować na istniejącym systemie demonstracyjnym: http://bottega.com.pl/ddd-cqrs-sample-project dążąc do modelowania wymagań na 2 i 3 poziomie wraz z implementacją wykonywalnych scenariuszy i specyfikacji z wykorzystaniem JBehave.

Komercyjne:
-Szkolenie Domain Driven Design - 22-24.10.2012
strona wydarzenia w ramach JDD
(uczestnictwo w konferencji jest obligatoryjne:)


- Java Developers Day - 25.10.2012 Prezentacja “Ports & Adapters – adaptacyjna architektura na miarę potrzeb”
Architektura Ports & Adapters jest syntezą współczesnej wiedzy na
temat rozwiązań stosowanych w systemach enterprise.

W jej giętkim mikro-jądrze znajdziemy miejsce na DDD, TDD, CqRS, Event
Sourcing i pluginy.
Jej twarda skorupa Portów oferuje skalowanie oraz zapewnia SAO Ready.
Natomiast zewnętrzna aura Adapterów umożliwia integrację przy pomocy:
receptorów zdarzeń, Sagi Biznesowej, Pipes and Filters, REST, WS
wspierając strategię rynkową multiscreen.

Całość w zintegrowanej formie, gdzie "wszystko jest na miejscu i
wszystko ma swoje miejsce".

Podczas prezentacji będę chciał przekonać Was do podejścia, w których wyłaniamy formę architektury systemu oraz aplikacji z treści przykładowych scenariuszy i wymagań. Wykorzystamy w tym celu techniki myślenia wizualnego oraz Building Blocks wchodzące w skład architektury Ports&Adapters.

wtorek, 9 października 2012

ORM - "The Vietnam of Computer Science"

...cytat Teda Newarda rozbawił mnie szczerze - ale to śmiech przez łzy. Martin Fowler natomiast pyta: Ale co w zamian?

Możemy uciec się do rozwiązań typu Datoms (Encja, Atrybut, Wartość, Timestamp) lub bardziej "semantycznego" Event Sorcingu.

Jednak są to rozwiązania specyficznych klas problemów (podróże w czasie, wektory uczące dla Sztucznych Sieci Neuronowych) lub problemów skali Googl/Twitter/Facebbok - mimo, że nie pracujemy w tych firmach, to lubimy się na nie powoływać w swych elaboratach architektonicznych:)

Natomiast w typowych systemach biznesowych wystarczy przyjęcie prostych i racjonalnych zasad doboru odpowiedniego młotka do odpowiedniej klasy problemu:
  • Obiekty persystentne to Agregaty, których granice są wyznaczane wg dobrych praktyk DDD: np. modelowanie niezmienników oraz modelowanie jednostki zmiany biznesowej
  • Do persystencji Agregatów używamy ORM, ponieważ dobrze zakreślone granice agregatów (w tym unikanie zbędnych połączeń) rozwiązują większość problemów
  • Do wydajnego odczytu danych przekrojowych nie używamy ORM - nie służą do tego typu zadań 
Proste, łatwe i... przyjemne:)
W razie problemów z wydajnością warto spróbować różnych form separacji z podejścia: Command-query Responsibility Segregation.

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

Więcej w archiwalnym poście, natomiast rozwinięcie w najbliższym numerze programistamag.pl



środa, 19 września 2012

Posmak Confitury

Na wstępie chciałbym podziękować wszystkim, którzy oddali głos na moją prezentację w plebiscycie konferencji Confitura 2012: Najlepsze i najbardziej komentowane prezentacje tegorocznej Confitury - podsumowanie ankiet. A przede wszystkim za determinację - nie spodziewałem się tak licznej publiczności w czerwcowe, upalne, sobotnie popołudnie.

Dzięki Wam warto pracować nad kolejnymi prezentacjami (mam też motywator aby zapisać się na lekce z emisji głosu i dykcji:P)

Dziękuję również organizatorom, a w szczególności Krzysztofowi Koziołowi, który mozolnie przerobił moją prezentację w prezi na screenshoty - po to aby połączyć je w parleys. Oto efekt jego pracy:


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

Właśnie przejrzałem komentarze, jakie zgłosiliście do mojej prezentacji. Dziękuję wszystkim za dobre słowa. Są one motywacją do dalszej pracy.

Chciałbym odpowiedzieć jednej osobie na komentarz: "Ale jedno zastanawia, image, przygarbiona sylwetka, zmęczenie? choroba? rok temu wygląd jak 'młody bóg'".

Heh... było dokładnie odwrotnie: teraz czuję tak właśnie, a wrażenie zewnętrznego obserwatora to tylko pozory...
- w ciągu 2 miesięcy pozbyłem się 15kg zbędnej masy (tłuszczowej a nie mięśniowej dzięki diecie paleolitycznej), przez co uwydatniły się moje zmarszczki:)
- utrata masy była jednak zbyt szybka, moje mięśnie szkieletowe i struktury mózgu odpowiedzialne za postawę i ruch nie zdążyły się przeprogramować. Ale już się wyprostowałem dzięki ćwiczeniom Feldenkraisa
- 3 dni wcześniej brałem udział (jako uczestnik) w ultra-intensywnym szkoleniu, które było wyczerpujące mentalnie, stąd może objawy somatyczne, ale zapewniam, że stan wewnętrzny był z goła odmienny
- co do image to wprost po szkoleniu wsiadłem do rumaka i (nie przekraczając prędkości) pędziłem aby zdążyć na swoją prezentację, więc nie było czasu na przyodzienie stroju galowego;)
- no i do tego upał... może nie tyle sam upał, co oświetlenie sceny, które podnosiło lokalną temperaturę chyba do 40 stopni C:)

Kilka osób pytało też: "Ale jakie ma to zastosowanie w mojej pracy?"
Szczerze mówiąc to wydaje mi się, że starałem się dawać przykłady i odniesienia do sytuacji z pracy zawodowej - być może z braku czasu nie podałem ich odpowiedniej ilości licząc na zdolność kojarzeniowe uczestników:P

czwartek, 13 września 2012

Klocki czy Puzzle?

Właśnie mija północ a wraz z nią tegoroczny Dzień Programisty.

Gdybyś mógł/mogła zażyczyć sobie z tej okazji prezent od Wielkiego Elektronika mając do wyboru Klocki i Puzzle, to co byś wybrał/wybrała?


Skąd to pytanie? Obie te rzeczy dostarczają rozrywki umysłowej, jednak zupełnie innego typu. Z klocków możesz zbudować coś co sam kreujesz. Mamy wolną rękę i ograniczenia jedynie co do rodzaju klocków i sposobu ich łączenia. Generalnie są pewne reguły i wiele punktów swobody. Puzzle natomiast to wyzwanie innego typu: nie mamy swobody i poruszamy się w z góry narzuconych przez kogoś "ciasnych regułach", problem polega na ogarnięciu dużej ilości informacji (jednego typu) bez możliwości wyjścia poza "ramy".

Pozwolę sobie teraz wysnuć paralelę (trudne słowo:) do naszej pracy. Niektóre zadania lub nawet całe projekty polegają na projektowaniu, kreowaniu, eksperymentowaniu a inne na utrzymaniu i łataniu tego co jest (np legacy).

Podczas pracy z różnego rodzaju zespołami programistycznymi zauważam generalnie 2 typy programistów: szczęśliwi z tego co robią i niezbyt zadowoleni. Często jest to skorelowane z rodzajem zadań jakie zostały im przydzielone i dopasowaniem rodzaju tych zadań do potrzeb emocjonalnych. I nie chcę tutaj wartościować, jaki rodzaj jest lepszy czy gorszy - każdy ma swoje osobiste preferencje.

Chodzi o to aby w miarę możliwości świadomie podejmować zadania tego typu, który zaspokaja nasze potrzeby kognitywne i emocjonalne. Zamiast biernie dryfować lub być popychanym czy używanym przez kogoś jako narzędzie, zacznij świadomie kierować swą karierą.

Tak więc z okazji swego święta przypomnij sobie: czym wolałeś/wolałaś się bawić w dzieciństwie - klockami czy puzzlami? "...a później zacznij to robić".

niedziela, 2 września 2012

DDD w Łodzi

W imieniu swoim jak i liderów Łódzkiego JUGa zapraszam w najbliższy wtorek (4 września) o godzinie 18:30 na prezentację poświęconą Domain Driven Design.

Prezentacja będzie dosyć ogólna i nie jest związana ściśle z Javą, tak więc zapraszamy entuzjastów różnych technologii.

Strona wydarzenia
Dyskusja na grupie Łódzkiego JUG

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

Prezentacja dostępna na prezi.com.
Prezentacja będzie koncepcyjnym rozwinięciem technik, o których mówiłem goszcząc w Łodzi ostatnim razem: Przewodnik strukturyzacji architektury systemu. 10,5 klasycznych technik programistycznych leżących u podstaw nowoczesnej inżynierii oprogramowania

środa, 29 sierpnia 2012

Diabeł tkwi w przerywanych liniach

Do czego prowadzi praca w paranoi polegającej na projektowaniu oczywistych oczywistości z pominięciem istotnych szczegółów: The Pragmatic Architect - To Boldly Go Where No One Has Gone Before

Autor w przykładach rozwiązań nawiązujących do jednego z Bulding Blocków DDD: Value Objects, spojrzał zaledwie przez dziurkę od klucza na wierzchołek góry lodowej. Więcej można znaleźć np. tu (w cenie, która w dniu publikacji posta jest bardzo atrakcyjna:).

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

Pierwszy komentarz pod artykułem jest wart takiej samej uwagi na sam artykuł.

wtorek, 21 sierpnia 2012

DDD&CqRS Leaven - wersja .NET (preview)

Entuzjastów platformy .NET (i nie tylko) zapraszam do zapoznania się z nową wersją naszego projektu DDD&CqRS Leaven: http://cqrssample.codeplex.com/

//==========================
Przy okazji chciałbym przedstawić nowego członka zespołu pracującego nad projektem: Michała Maca - bloggera i nowego trenera w firmie Bottega.

poniedziałek, 13 sierpnia 2012

Puste naczynia brzęczą najgłośniej

http://www.fastcompany.com/3000226/link-between-quietness-and-productivity

//=================================
Dziś wrzucam na próbę treść z pogranicza pracy zawodowej i pracy nad sobą. Jeżeli będzie Was interesowała tego typu tematyka, to posty (bardziej treściwe) będą pojawiać się częściej.

piątek, 20 lipca 2012

DDD krok po kroku - część III

W najnowszym numerze programistamag.pl ukazała się trzecia część naszej serii tekstów poświęconych DDD: "Domain Driven Design krok po kroku Część III: Szczegóły implementacji aplikacji wykorzystującej DDD na platformie Java – Spring Framework i Hibernate"

Tym razem wchodzimy w szczegóły wykorzystania Spring (lub ogólnie: kontenera Inverion of Control oferującego 3 techniki odwracania kontroli: Dependency Injection, Events, Aspect Oriented Programming) i JPA (ogólnie: mapera relacyjno-obiektowego).

//===========================
Zapraszam do dyskusji na temat podejmowanych w tekście decyzji projektowych.

czwartek, 19 lipca 2012

Implementing Domain-Driven Design

Dziś ukazała się elektryczna wersja najnowszej książki autorstwa Vaughna Vernona poświęconej praktycznym aspektom implementacji DDD: "Implementing Domain-Driven Design", którą możecie zakupić na safari books online.

Recenzję opublikuję zaraz po tym jak skończę ją czytać (ale w kolejce priorytetowej znajduje się ok 10 pozycji "miękkich").

Już teraz mogę napisać, że mając wcześniej dostęp do pewnych jej części, śmiało mogę polecić nawet zaawansowanym praktykom DDD.


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

Nieskromnie dodam (po przejrzeniu spisu treści), że książka stworzona pod nadzorem elity współczesnej inżynierii oprogramowania (M. Fowler, E. Evans, G. Young, U. Dahan) tylko nieznacznie wychodzi merytoryką poza nasz projekt DDD-CqRS Leaven:]

niedziela, 1 lipca 2012

Confitura 2012 skonsumowana

Confitura 2012 za nami.
Na wstępie chciałbym podziękować wszystkim uczestnikom mojej prezentacji. Obdarzyliście mnie największymi brawami (uściślając: pod względem natężenia dźwięki i czasu trwania) jakie do tej pory dostałem w życiu!

Dziękuję, właśnie to sprawia, że warto pracować nad prezentacjami.

Nie chciałem mówić tego podczas prezentacji, ale zostało mi jeszcze ok 1/4 materiałów. Resztę możecie zobaczyć pod tym adresem. Słowa kluczowe z prezentacji pozwolą Wam na dalsze poszukiwania. Zresztą, taka była idea prezentacji: przegląd kilkunastu tematów i inspiracja do własnych poszukiwań.

Po prezentacji powtarzały się 2 pytania:
1. "O co chodzi z tymi 2 procesorami w mózgu i umysłem znajdującym się poza głównymi procesorami (poza mózgiem, w ciele)?"
Jedynie wspomniałem o tym, jednak rozwinięcie zajęłoby nam kilka godzin (a tak na prawdę kilka miesięcy:) Jedak - tak jak się spodziewałem - wzbudziło to spore zainteresowanie, dlatego odsyłam do 3 podstawowych źródeł: - Pragmatic Thinking and Learning: Refactor Your Wetware - lekka, łatwa i przyjemna synteza współczesnej wiedzy z zakresu neuropsychologii, psychologii, socjologii z elementami NLP. Napisana przez programistę, więc czyta się doskonale. Doskonała na początek.
- The Master and His Emissary: The Divided Brain and the Making of the Western World - głębsza i nieco bardziej bardziej wymagająca.
- wykłady profesora Włodzisława Ducha z zakresu wstępu do kognitywistyki.

2. "Jaki jest ten szósty poziom w Modelu Dreyfus?" - zaznaczyłem temat, ale nie zdążyłem o tym powiedzieć. Najwyższy poziom to Guru. Guru to taki Ekspert, który mówiąc wprost i bez ogródek nie jest dupkiem:) Idąc do takiego Eksperta zawsze dostaniemy, jeżeli nie odpowiedź dopasowaną do naszego poziomu, to "przynajmniej" natchnienie i kierunek w stronę samodzielnego rozwiązania.


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

Niestety nigdzie nie mogłem naleźć wyjaśnienia fenomenu Twittera;)
O co kurcze chodzi z tym, że ludzie siedzą na prezentacji i zamiast wchłaniać zawartość, wolą tweetować. Czyli de facto "wypróżniać bufory", które zapełnił generator szumu (L-Brain w modelu 2 procesorów), łudząc się w narcystycznym przekonaniu, że kogoś może to interesować...:P

wtorek, 29 maja 2012

Druga część z serii artykułów poświęconych DDD

W najnowszym programistamag.pl został opublikowany kolejny z serii artykuł mego autorstwa poświęcony DDD: Domain Driven Design krok po kroku część II : Zaawansowane modelowanie DDD, techniki strategiczne: konteksty i architektura zdarzeniowa.

Zapraszam do lektury.

wtorek, 22 maja 2012

JUG Trójmiasto - prezentacja

Zapraszam entuzjastów inżynierii oprogramowania i Javy (ale nie tylko Javy) na prezentację, którą wygłoszę w najbliższy czwartek (25.05) w ramach trójmiejskiego JUGa.

Prezentacja:
Przewodnik strukturyzacji architektury systemu. 10,5 klasycznych technik programistycznych leżących u podstaw nowoczesnej inżynierii oprogramowania
jest dostępna na prezi.com.

Data: 24.05.2012 godzina: 19:00
Miejsce spotkania: Gdański Inkubator Przedsiębiorczości http://inkubatorstarter.pl
Gdańsk, ul. Lęborska 3B.

poniedziałek, 7 maja 2012

Dwa smaki Object Oriented Design

W myśl "starego chińskiego przysłowia": "lepiej podlinkować dobry post niż go przepisywać na język polski" polecam prosty, ale dający bodziec do głębszego przemyślenia tekst: Two flavors of DDD.

W tytule mamy co prawda DDD, ale tekst ma ogólne przesłanie, dla każdego projektanta (a który programista nie jest projektantem), w zakresie:
  • enkapsulacji - głębokiej enkapsulacji na poziomie caouplingu pomiędzy obiektami
  • stosowalności ORM
  • otwartości na zmiany
  • problemu danych historycznych, który jest stary jak IT...

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

Po raz kolejny wracamy do podstawowych podstaw, których braki po prostu zabijają projekty...

wtorek, 17 kwietnia 2012

Prezentacja na Silesia JUG

W najbliższy czwartek 19 kwietnia o 18:30 będę prowadził w ramach Silesia JUG prezentację "Ścisły przewodnik po aspektach miękkich dla ekspertów IT" - abstrakt i "slajdy" w tym poście.

Zainteresowanych (nie tylko ze świata Javy) zapraszam serdecznie.

czwartek, 22 marca 2012

Programistamag.pl - nowy periodyk branżowy

Wczoraj ukazał się premierowy numer nowego czasopisma dla programistów: http://programistamag.pl.

Znajdziecie w nim między innymi (popełniony przeze mnie) pierwszy z serii artykuł poświęcony podstawom Domain Driven Design - tak zwanym Building Blocks.

Seria poświęcona DDD będzie oparta o nasz referencyjny projekt Leaven.

Zachęcam do lektury i komentowania tekstu.

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

Dostęp do magazynu w formacie PDF jest bezpłatny; płatne wersje to Kindle i klasyczny druk.

środa, 21 marca 2012

Average polish Java developer is not an idiot for Zeus' sake!

If You live in Western Europe or US and visit Poland, You may strike general impression (looking at airport, cars, clothes fashion) that Poland is rather poor country.

Therefore: if society could not manage to generate wealthy "system", than You may infer that only logical explanation is that human beings living in given area must be somehow stupid. I don't know much about macro/psycho/social/ - economy, but let's temporarily agree about this hypothesis.

Average Java developer in Poland has mostly just a Master Degree (99,9%) in Computer Science (I guess that over 70%), usually there are just few Phds per company.

So, maybe Average Java developer in Poland is not a genius, but for Zeus' sake: when giving a talk at Java conference You don't have to explain to him/her that:
  • methods should be short
  • code should be simple, simple, simple
  • 2.0 - 1.1 is almost 0.9 when operating on doubles
  • duplication in code is bad (but not always!!!)
  • SSD is faster than HDD
We get it, really:P
And some of us even understand laser at the quantum level:PPP

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

33 Degree Conference was a great event (again), I would like to thank every single one for awesome vibes, see You next year:)))
Special thanks to Grzesiek!
Full conference summary at the weekend, after coming back home from workshop...

sobota, 17 marca 2012

Prezentacje na 33rd Degree

W najbliższy wtorek 20. marca będę miał przyjemność przedstawić dwie prezentacje podczas konferencji 33rd Degree.

Niezdecydowanych co do wyboru ścieżki uczestników zapraszam do zapoznania się z prezentacjami. Co prawda są to jedynie "ścieżki myśli" (raczej dla mnie, prowadzące wątek), które bez narracji zawierają max. 20% treści, ale mam nadzieję, że pozwolą Wam zorientować się czy tematyka i jej zakres może być interesująca lub nie.


Pierwsza prezentacja będzie poświęcona zagadnieniom "miękkim". Tradycyjnie wplatam "miękkie" wątki w każdą swą prezentację, jednak tym razem będzie to 100% treści (i zero kodu:) Jednak doszyć szybko doprowadzimy do "ścięcia" się białka i wyszukania "twardych" konkretów - co symbolizuje gubernator na pierwszym "slajdzie":)

abstrakt: Ścisły przewodnik po aspektach miękkich dla ekspertów IT





Druga prezentacja jest dla odmiany techniczna w każdym calu - konkretne problemy i konkretne techniki inżynieryjne ich rozwiązania.

abstrakt: Przewodnik po strukturyzacji systemu. 10,5 klasycznych technik programistycznych leżących u podstaw nowoczesnej inżynierii oprogramowania





//===============================
Materiały są w wersji Alpha, błędy nie zostały jeszcze poddane korekcie:)

piątek, 2 marca 2012

Racjonalne wykorzystanie JPA

W poprzednim poście opisałem klasyczny problem wydajnościowy N+1 Select Problem występujący podczas korzystania z Java Persistence API, wraz z kilkoma podejściami do zabezpieczenia się przed jego powstawaniem.

W komentarzach pojawił się pewien wątek, który chciałbym teraz rozwinąć...

Zastanowimy się nad racjonalnym wykorzystaniem narzędzia jakim jest maper relacyjno-obiektowy. Jak to zwykle z racjonalnym myśleniem bywa - niesie ono ze sobą zwykle dodatkowe skutki uboczne w postaci nieoczekiwanych korzyści. W tym wypadku będzie to dodatkowa poprawa wydajności.

Co? Po co? Dlaczego tak?

W jakim celu mapujemy świat relacyjny na obiektowy?
Być może po to aby:
  • Pobierać w wygodny sposób obiekty biznesowe - wraz z wygodnymi mechanizmami typu Lazy Loading
  • Wykonywać na nich operacje biznesowe zmieniające ich stan - możemy tutaj tworzyć zarówno anemiczne encje modyfikowane przez serwisy jak również projektować prawdziwe obiekty modelujące reguły i niezmienniki biznesowe (styl Domain Driven Design)
  • Utrwalać stan obiektów biznesowych - stan, który zmienił się w poprzednim kroku (korzystając z wygodnych mechanizmów wykrywania "brudzenia" i mechanizmu kaskadowego zapisu całych grafów obiektów)
Jeżeli używasz JPA do tych klas problemów, to używasz odpowiedniego młotka do odpowiedniej klasy problemu. Czyli pobieram obiekt (JEDEN, no dwa, góra cy;) biznesowy, zmieniam jego stan, zapisuję go.

Pisząc zmieniam stan nie mam na myśli "edytuję podpinając pod formularz". Mam na myśli logikę aplikacji (modelującą Use Case/User Story), która modyfikuje mój obiekt biznesowy (uruchamiając jego metody biznesowe lub settery jeżeli jest on anemiczny). Przykład gdzie Order i Invoice to obiekty persystentne:

 public void approveOrder(Long orderId) {
        Order order = orderRepository.load(orderId);

        //sample: Specification Design Pattern
        Specification<Order> orderSpecification = generateSpecification(systemUser);
        if (!orderSpecification.isSatisfiedBy(order))
            throw new OrderOperationException("Order does not meet specification", order.getEntityId());

        // sample: call Domain Logic
        order.submit();
        // sample: call Domain Service (Bookkeeper)
        Invoice invoice = invoicingService.issuance(order, generateTaxPolicy(systemUser));

        invoiceRepository.save(invoice);
        orderRepository.save(order);
    }

Link do kodu.


Zawsze?

Jeżeli natomiast chcę wyświetlić na ekranie dane, np. dane przekrojowe, np w postaci tabelki (ludzie biznesu uwielbiają tabelki, najlepiej aby dało się przestawiać kolejność ich kolumn;) to narzędzie pod tytułem JPA nie jest odpowiednim młotkiem do tego problemu. W tym wypadku na każdym etapie postępuję nieracjonalnie:
  • Pobieram z mapera listę obiektów (zamapowanych na całe tabelki w bazie) gdy potrzebuję na ekranie jedynie kilku kolumn z każdej tabelki (dla bazy nie robi to różnicy, ale gdy maszyna serwująca bazę lub klient je zdalna to wówczas zaznamy odczuwać skutki tej decyzji)
  • Mam możliwość korzystania z mechanizmu Lazy Loadingu, który nie ma sensu dla operacji typu "pobierz dane do wyświetlenia"
  • Silnik mapera wykonuje niepotrzebne operacje związane z LL i wykrywaniem "brudzenia" - przecież nie będę modyfikował tych obiektów, chcę jedynie coś wyświetlić
  • Zdradzam model biznesowy warstwie prezentacji. Być może w prostych aplikacjach z prezentacją w technologii webowej (ta sama maszyna pobiera i prezentuje dane) nie jest to problem - dodatkowo zyskujemy produktywność w pracy. Ale jeżeli klienty (nie klienci) są zdalne (np Android)? Zdradzanie modelu domenowego wiąże się z drastycznym spadkiem bezpieczeństwa (wsteczna inżynieria) oraz z koniecznością koordynacji prac zespołów pracujących nad "klientem" i "serwerem", że o zapewnianiu kompatybilności starszych wersji klientów nie wspomnę. Niby banały, jednak w niektórzy ewangelizatorzy EE zachęcają do zwracania encji ponad warstwę serwisów (sic!)


Klasa problemu <=> Klasa rozwiązania

W każdym systemie mamy wyraźnie rozróżnienie na odczyt danych i modyfikację danych. Pisałem już jakiś czas temu o paradygmacie Command-query Seapration, z którego wyłoniła się architektura Command-query Responsibility Segregation.

Nie chcę się powtarzać, zatem w materiałach bloga (link na górze po prawej) znajdziecie prezentację na ten temat, polecam też artykuł samego mistrza: Martina Fowlera.

Separacja

Tak więc donosząc się do pytania Andrzeja z poprzedniego posta: Jak najbardziej konstrukcja SELECY NEW MyDTO(encja.pole1, ecnja.pole2) FROM Encja encja jest na miejscu. W przypadku gdy chodzi o zwrócenie danych do prezentacji (modelowanych jako DTO) a nie pobranie obiektów biznesowych do wykonania na nich operacji biznesowych.

Separację możemy poprowadzić jeszcze "głębiej" i dokonać projekcji modelu domenowego, który utrzymujemy w III postaci normalnej do postaci płaskiej, odpowiedniej do odczytu. W tym celu możemy zastosować Widoki Zmaterializowane lub np. odświeżać model Read przy pomocy zdarzeń domenowych.

Najmniej racjonalną rzeczą jaką możemy zrobić to pobierać encje JPA i przepakowywać je na DTO. Po co pobierać te dane (ryzykując N+1SP) skoro i tak musimy wykonać pracę (kodowanie, załączenie automatu) przepakowania?

Wydajność ++

Ale zostawmy zaawansowane architektury przygotowane do skalowania...

Jeżeli już decydujemy się na pobieranie poszczególnych kolumn z bazy, to dlaczego nie użyć czystego SQL zamiast HQL (konstrukcji SELECT NEW)? Przecież skoro wiem, że pewnych miejscach pobieram dane jedynie do odczytu, to być może warto zestawić osobną pulę połączeń z bazą - połączeń read-only. Być może baza, której używasz będzie wówczas działać nieco lepiej...:)

W takim wypadku warto użyć lekkiego mapera typu myBatis, którego użyję w celu mapowania Result Set na paczki danych (DTO) a nie na obiekty biznesowe służce do wykonywania operacji biznesowych!

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

Pracując z Hibernate (od 2003r, od wersji 2.0) zawsze, w każdym jednym projekcie - małym i dużym (1200 tabel) dochodziło do sytuacji przepisania pewnych zapytań na czysty SQL z powodu wydajności. MyBatis na prawdę działa:)

Przykłady architektury, która wyraźnie rozdziela operacje odczytu i zapisu: Domain Driven Design & Command-query Responsibility Segregation sample project - Java, Spring, JPA

wtorek, 28 lutego 2012

Automatyczne wykrywanie n+1 Select Problem w EJB (ale niekoniecznie)

N+1 Select Problem to... problem. Poważny problem:)
Temat jest stary jak Hibernate, ale w swej pracy wciąż spotykam zespoły, które nie zdają sobie z niego sprawy. Tak więc jeżeli nie wiesz czy masz n+1 SP to znaczy, że go masz.

Definicja problemu

Idea problemu jest prosta: załóżmy, że mamy encję User, która zawiera w sobie listę encji Address.
@Entity
public class User{
  @OneToMany
  @JoinColumn("user_id")
  List<Address> addresses;
}
Teraz jeżeli pobierzemy listę użytkowników a następnie iterując po tej liście dla każdego użytkownika zaczniemy przeglądać jego adresy, to wówczas możemy spodziewać się następującej interakcji z bazą danych:
1 x SELECT ... FROM Users - zwróci nam n użytkowników
N x SELECT ... FROM Address

Wykrywanie białkowe

Jeżeli w firmie gdzie pracujesz porządku w bazie pilnuje DB-Nazi, to możesz spodziewać się nagłej wizyty tego smutnego Pana...
Jeżeli nie masz takiego szczęścia (nie jest to sarkazm) to problem wykryjesz obserwując konsolę.
A jeżeli w swojej bazie developerskiej posiadasz 1 Adres (generalnie: operujesz na bardzo małych n) to zapewne problem uświadczysz dopiero na produkcji.

Wykrywanie automatyczne

Możemy stosunkowo łatwo zbadać ilość poleceń SQL wysyłanych do bazy danych. W tym celu posłużymy się klasą Statistics.
Aby zdiagnozować ilość operacji wykonywanych przez nasze komponenty biznesowe (serwisy, nie oszukujmy się;) możemy posłużyć się technikami AOP. Przykładowo w Springu mamy możliwość wpięcia Porady (Advice). Natomiast w EJB możemy skorzystać z Interoceptorów ("poor man's AOP" w wydaniu EE):
package pl.com.bottega.common.support.interceptors;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;

import org.hibernate.SessionFactory;
import org.hibernate.ejb.EntityManagerFactoryImpl;
import org.hibernate.event.EventListeners;
import org.hibernate.stat.Statistics;
import org.jboss.jpa.injection.InjectedEntityManagerFactory;

public class NPlusOneSelectProblemDetectingInterceptor {

 @PersistenceUnit
 private EntityManagerFactory entityManagerFactory; 
 
 
 @AroundInvoke
 public Object countStatements(InvocationContext invContext) throws Exception {
  InjectedEntityManagerFactory iemf = (InjectedEntityManagerFactory) entityManagerFactory;
  EntityManagerFactoryImpl hemf = (EntityManagerFactoryImpl) iemf.getDelegate(); 
  
  SessionFactory sessionFactory = hemf.getSessionFactory();
  Statistics statistics = sessionFactory.getStatistics();
  statistics.setStatisticsEnabled(true);

  long before = statistics.getPrepareStatementCount();
  
  Object result = invContext.proceed();

  long count = statistics.getPrepareStatementCount() - before;
  if (count > 30){
    String message = invContext.getTarget().getClass() + "->" + invContext.getMethod().getName() + " statements: " + count;
    //TODO wysłać maila do db-nazi 
  }
  return result;
 }
}

Nasz interoceptor jest stosunkowo prosty: sprawdza ilość Prepare Statement przed i po wywołaniu EJB. Jeżeli różnica przekracza badany pułap, wówczas "wiedz, że coś się dzieje".

Przechwycenie wszystkich EJB w pliku ejb-jar.xml:

 
  
   pl.com.bottega.common.support.interceptors.NPlusOneSelectProblemDetectingInterceptor
   
  
 
 
  
   *
    pl.com.bottega.common.support.interceptors.NPlusOneSelectProblemDetectingInterceptor
  
 

Problem wyższej warstwy

Drzewiej bywało tak, że transakcje opiewały jedynie warstwę logiki (nazwa umowna). W warstwie prezentacji Transakcje były niedostępne, przez co Entity Manager (Session w Hibernate) nie wspierał Lazy Loadingu. Dzięki temu programista dostawał wyjątek gdy LazyInitializationException gdy chciał "dociągać" dane z warstwy prezentacji. Było to dobre, ponieważ skłaniało do zastanowienia: co ja właściwie chcę zrobić, jakich danych potrzebuję...
Obecnie niemal standardem jest (anty) pattern Open Session in View, który daje możliwość naszym kontrolkom GUI na dociąganie danych. I tak na przykład tabelka renderująca listę użytkowników, może w jednej z kolumn renderować listę adresów. N+1 SP zapewniony...

Aby wykryć problem powodowany przez warstwę prezentacji należało by stworzyć odpowiedni Filtr na poziomie Servlet API.

Naprawa N+1 SP

Istnieje kilka szybkich "obejść" oraz jedno rzetelne, prawdziwe rozwiązanie:
  • Rozproszony cache Encji - ja podaję go w formie żartu, ale czasem widuje się to rozwiązanie. Być może jest ono uzasadnione, ale warto się zastanowić dlaczego go potrzebuję i jaką złożoność przypadkową ono wprowadza...
  • @BatchSize - redukuje problem, działa na ślepo konsumując pamięc, ale daje szybki efekt, można ustawić defaultowy, globlany w XML
  • @Fetch - wyspecyfikowanie w jaki sposób życzymy sobie pobierać chciwie/łapczywie/gorliwie (piękne tłumaczenia słowa EAGER) kolekcje. Uwaga: HQL ignoruje wszystko oprócz Subselect, Criteria API respektuje wszystko

Rozwiązanie rzetelne

Dedykowane zapytania "szyte na miarę" danego przypadku:
SELECT DISTINCT u FROM User u LEFT JOIN FETCH u.addresses

Warto wiedzieć, że w tym wypadku setMaxResult działa w sposób niezdefiniowany oraz, że nie da się chciwie pobrać 2 Toreb (Bag). Bag to pojęcie w Hibernate, które oznacza kolekcję charakteryzującą się brakiem porządku (tak jak Set) ale zezwoleniem na duplikaty. Bag w Hibernate to na poziomie Javy List bez @IndexColumn... ehhh smaczki JPA...:P

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

W przypadku gdy zależy nam na wydajności nic nie zastąpi czystego SQLa tuningowanego przez starego, dobrego DB-Nazi, który zna się na swoim fachu...

poniedziałek, 27 lutego 2012

Musisz to zobaczyć!

Jeżeli jesteś developerem (a któż inny zaglądnął by w to miejsce) to na prawdę musisz to zobaczyć.
http://vimeo.com/36579366

Jak nazwiemy to "coś"? Example Driven Development? Feeling DD? TDD 2.0? What You See is What You Code?

Czekam na propozycje...

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

I nie mówcie, że zabawka użyta przy wizualizacji Binary Search to gadżet dla początkujących... wszyscy znamy hakierów, którym mogłoby się to przydać w codziennej pracy:P

A teraz czas sprawdzić czy nasz serwer EE skończył już redeploy...

poniedziałek, 30 stycznia 2012

Fantomowe tabelki w JSF

W niniejszym poście przyjrzymy się pewnej anomalii występującej w JSF, której skutki potencjalnie mogą być katastrofalne.
Anomalia została dobrze rozpoznana dosyć dawno, jednak jak pokazuje moje doświadczenie w pracy z zespołami korzystającymi z JSF, nie jest ona uświadomiona.
Dlatego dla tych z czytelników, którzy używają JSF i nie spotkali się ze zjawiskiem "klikania w nieodpowiednie wiersze tabelki" lektura posta jest obowiązkowa:)

Problematyczny scenariusz:
1. Użytkownik A wyświetla na stronie tabelkę z listą rekordów (Encje JPA lub DTO)
Na ekranie dla każdego rekordu mamy możliwość jego edycji/usunięcia poprzez Postback.

2. Podczas gdy użytkownik A delektuje się widokiem zaokrąglonych rogów na naszej stronie, użytkownik B (w tak zwanym międzyczasie) dokonuje w bazie zmiany danych, które są prezentowane na ekranie użytkownika A.
Może być to usunięcie danych lub edycja takich atrybutów, które wpłyną na ilość lub kolejność danych zwracanych przez zapytanie, które używa ekran użytkownika A.

3. Użytkownik A, po zaspokojeniu swych potrzeb estetycznych, klika przykładowo w pierwszy wiersz tabelki w celu usunięcia/modyfikacji rekordu.

4. Ku zdziwieniu użytkownika A, system poddał usunięciu/edycji zupełnie inny rekord niż zamierzony.

Zjawisko to pozwoliłem sobie nazwać Fantomową tabelką - ot jako żarcik techniczny będący paralelą (trudne słowo) do Anomalii Transakcji.

Przykład kodu

Managed Bean:
@ManagedBean()
public class UsersControler{ 
 
 @ManagedProperty("#{userFinder}")
 private UserFinder userFinder;
 
 @ManagedProperty("#{userManagement}")
 private UserManagement userManagement;
 
        //Bean o zasięgu sesji pamiętający nasze kryteria wyszukiwania
 @ManagedProperty("#{usersSearchCriteria}")
 private UsersSearchCriteria usersSearchCriteria;

 private List<User> users;
 
 private User selected;
 
 
 @PostConstruct
 public void search(){  
  users = userFinder.findUsers(usersSearchCriteria.getFirstname(), usersSearchCriteria.getLastname(), null, null);  
 } 

 public void remove(){
  userManagement.deleteUser(selected.getId());
  //search(); - zbędne dla zasięgu Request, konieczne dla View aby odświeżyć
 }
 
 public void remove2(Long id){ 
  userManagement.deleteUser(id);
  //search(); - zbędne dla zasięgu Request, konieczne dla View aby odświeżyć
 }   
}

Powyższy ManagedBean ma domyślny zasięg Request (nie chcemy przecież obciążać stanu sesji listą użytkowników).

Nasz bean ma wstrzyknięte 2 obiekty z warstwy aplikacji: UserFinder (wyszukujący użytkowników), UserManagement (operujący na użytkownikach - w przykładzie usuwamy użytkowników, ale problem jest ogólny - generalnie chodzi o jakąkolwiek modyfikację, która zmieni resultat działania UserFinder.findUsers )

Zwróćcie uwagę, iż kryteria wyszukiwania z formularza nie przechowywane w kontrolerze (który ma zasięg Request) a we wstrzykniętym Modelu o zasięgu Sesji.



    
     
     
      imie:  nazwisko: 
       
       
       
           
       
     
   
    
     ID
     #{_u.id}
    
 
    
    
     
      
      
     
                         
    
         
                
    

Widok jest bardzo prosty: tabelka iteruje po kolekcji użytkowników. Dla każdego z nich wyświetla ID (aby organoleptycznie zaobserwować problem) oraz umożliwia usunięcie (w ogólności modyfikację stanu bazy mającą wpływ na listę) użytkownika. Technicznie mamy tutaj dwa podejścia do przekazywania "klikniętego" użytkownika na Serwer: poprzez f:setPropertyActionListener oraz dzięki wywołaniu metody z parametrem.

To czy przekazujemy ID użytkownika czy obiekt klasy User nie ma znaczenia dla eksperymentu.

Dlaczego tak się dzieje

Załóżmy, że podczas pierwszego renderowania strony do pierwszego wiersza tabelki był "podpięty" pierwszy wiersz z wynikowej listy - użytkownik o id = 1.
Załóżmy, że później - po zmianie stanu bazy - pierwszy użytkownik na liście wynikowej pobranej z bazy ma id = 2.

Silnik JSF podczas postback odtwarza drzewo komponentów graficznych. Następnie "rozsmarowuje" na tym drzewie model. Tak więc podczas postback do pierwszego wiersza tabeli może podpiąć użytkownika o id = 2.

Model zdarzeń w JSF (zgodnie z nazwą Java Server Faces) odbywa się w kontekście serwera, czyli silnik ma informację o numerze klikniętego wiersza w tabelce (nie o id klikniętego usera). Dalej na podstawie klikniętego wiersza, zbiera z tego wiersza model i ten model traktuje jako "kliknięty". Jak widać - zakłada optymistycznie, że tak jest:)

Jeżeli przy postbacku model pobrany z bazy będzie inny - trudno... :P


Dlaczego często nie widać problemu

Programiści JSF często z powodu kłopotów z ogarnięciem złożoności zasięgów życia ManagedBeanów decydują się na rozwiązania "bo działa" i rozszerzają zasięg życia niemal wszystkich ich do Sesji. W przypadku zasięgu sesji nie odtwarzamy modelu danych na podstawie bazy lecz na podstawie ViewState zatem problem z klikaniem w fantomy jest po prostu ukryty - nie występuje. Czyli przy okazji, jako skutego uboczny niechlujstwa, zabezpieczamy się przez błędem fantomowych danych:)

Jeżeli zależy nam na zasobach lub świeżości danych, wówczas musimy wysilić się na rezygnację z Sesji gdzie tylko jest to możliwe i zaczyna się zabawa...

Rozwiązania

1. Zasięg View/Session
Przechowywanie list w Sesji to zwykle słaby pomysł, ale możemy zdecydować się na ich przechowywanie w zasięgu View, który trwa dopóki znajdujemy się na tej samej stronie (GET zrywa ten zasięg).
@ManagedBean()
@ViewScoped
public class UsersControler{

Można pokusić się o wydzielenie samego modelu prezentacji do osobnego ManagedBeana o zasięgu View tak aby nie przechowywać tam całego kontrolera, który jest zbędny i powinien żyć w Request. Wówczas wstrzykujemy model do kontrolera, napełniamy go w kontrolerze, po czym kontroler może już "umrzeć".


2. Ukryte Pole

Jeżeli nie możemy pozwolić sobie na przechowywanie stanu widoku, wówczas pewnym rozwiązaniem, jest rezygnacja z mechanizmów JSF do wskazywania klikniętego wiersza. Nasze buttony powinny przy pomocy JS ustawiać ukryte pole formularza na wartość id modelu wiersza i submitować to pole na managedbeana.


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

Po raz kolejny mamy do czynienia z sytuacją, gdzie próba ukrycia złożoności esencjalnej skutkuje wyciekiem jeszcze większej ilości złożoności przypadkowej.
"...życia nie oszukasz."

wtorek, 3 stycznia 2012

Dopamina Driven Development

Jaki wpływ na tworzenie kodu mogą mieć wytryski dopaminy?
Co wspólnego ma nikotyna z TDD?
Dowiecie się w 22. minucie i 30. sekundzie prezentacji Things I Wish I'd Known od samego twórcy Springa - Roda Johnsona:)


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

Generalnie bardzo polecam obejrzenie całej prezentacji, ale uprzedzam - nie ma w niej ani linijki kodu:)