All we do is looking for some way to fulfill our needs.

piątek, 25 lutego 2011

Tagged under: , , ,

Jaka nazwa dla tej metody?

public class OptionsAwareObject {  
    private Options options;  
      
    public void updateOptions(String fontName, int fontSize) {  
       options.setFontName(fontName);  
       options.setFontSize(fontSize);  
    }  
 }  
   
 class Options {  
   
    private int foregroundColor;  
      
    private int backgroundColor;  
      
    private String fontName;  
      
    private int fontSize; 
    // ...
}  

Czy updateOptions to dobra nazwa dla tej metody? Oczywiście, że nie! updateOptions jest ogólną nazwą, która sugerowałaby całościową aktualizacji opcji. Tymczasem my aktualizujemy tylko informacje nt. czcionki. Odpowiedzialnością metody jest zatem zmiana opcji związanych z czcionką. Lepszą nazwą byłaby:

public void updateFontOptions(String fontName, int fontSize) {  //...
Tagged under:

Antylitania do programistów

Nienawidzę Was za to że:
  • skupiacie się nad tym jakie ficzery ma Wasze IDE zamiast skupiać się na tym, jakich ficzerów potrzebuje Wasz klient/użytkownik,
  • klepanie w klawiaturę nazywacie myśleniem,
  • hektolitry czasu wyrzucacie w błoto testując manualnie swój kod,
  • więcej czasu spędzacie na walkę z frejmłorkami niż na dostarczaniu wartości dla końcowych użytkowników,
  • kodujecie wiele godzin nie zadając sobie pytania "co ja tak naprawdę robię",
  • naiwnie wierzycie, że technologie i narzędzia rozwiążą wasze problemy,
  • naiwnie wierzycie, że dobry algorytm jest ważniejszy od dobrego zrozumienia wymagań,
  • naiwnie wierzycie, że Wasza intuicja wystarczy w tworzeniu dobrego kodu,
  • naiwnie wierzycie, że jesteście w stanie ogarnąć złożoność kawałka systemu z którym pracujecie,
  • zgadzacie się na nierealne terminy,
  • że piszecie kiepski kod, znajdując na to wiele racjonalizacji (bo nie ma czasu),
  • w głowach tworzycie fragmenty kodu mimo że jeszcze dobrze nie wiecie co trzeba zrobić,
  • domyślacie się co trzeba zrobić, zamiast doprecyzować,
  • bezmyślnie podążacie za technologią, której używacie,
  • nie rozumiecie narzędzi i technologii, których używacie,
  • zamykacie się w swoim kawałku kodu, zrywając kontakt ze światem,
  • sądzicie, że to wszystko wina kierowników lub klienta i nie jesteście w stanie z tym nic zrobić.

... mimo że kocham bo sam jestem programistą.

sobota, 19 lutego 2011

Tagged under:

Call for ... code samples

Chętnie przedstawiłbym ideę naturalnego porządku refaktoryzacji na przykładowym kodzie. Niestety (co jest oczywiste rzecz jasna) nie mogę użyć kodu produkcyjnego klientów, a nie mam czasu przygotowywać do tego celu przykładu. Ale być może ktoś miałby chciałby na ten cel przeznaczyć swój kawałek kodu, projektu, który nie ma zbyt dużych (w zasadzie żadnych) obostrzeń co do publicznej publikacji.
Główne założenie to musi być w kodzie co refaktoryzować ;-)

W razie zainteresowania proszę o kontakt m [kropka] sieraczkiewicz [AT] bns [kropka] it.

wtorek, 15 lutego 2011

Tagged under: ,

Młody kierowniku/team liderze! Opamiętaj się!

Chyba nie napisze nic nowego... ale to tylko fakt, że historia lubi się powtarzać... bezustannie (vide: Marsz ku klęsce).

Otóż
Często powtarzanym, tragicznym w skutkach, nieprofesjonalnym działaniem drogi kierowniku/team liderze jest zobowiązywanie się do mało realnych terminów.

Naiwnie proste, można by rzec oczywiste, a jednak powtarza się. Dobrze o tym wiem, bo sam popełniałem nieraz ten błąd. Dlaczego zobowiązujemy się do mało realnych terminów:
a) bo jest presja kogoś z zewnątrz (klienta, menedżera, dyrektora),
b) bo wytwarzam presję wewnętrzną (chcę pokazać, że jesteśmy naprawdę dobrzy),
c) bo kompletnie nie mam pojęcia (albo mam pojęcie ale tylko trochę), co rzeczywiście trzeba zrobić w projekcie,
d) ??? - proszę o podpowiedzi :)

Co do pierwszych dwóch podpunktów rozwiązanie jest (wydaje się) proste - potrzeba asertywności i zwykłej szczerości wobec siebie i wobec przełożonych, tudzież klienta. Ta trudność, szczególnie jeśli się zaczyna (lub ma się niewielkie doświadczenie), wymaga często wyjście poza strefę komfortu - powiedzieć, że się nie da (w tym czasie).
I oczywiście można napotkać opór/sprzeciw, ale też najczęściej można pokazać swój profesjonalizm, który w tym przypadku zdefiniowałbym jako "Nie zobowiązuje się do niekonkretnych czy nierealnych terminów".
Często słyszę pytanie: "A jak zrealizować projekt, w którym już wiadomo, że jest za mało czasu, że za mało ludzi, że niejasne wymagania. Jakie są najlepsze praktyki". Odpowiedź jest prosta "Nie zgadzaj się na to, a raczej - negocjuj". Pokaż dlaczego termin jest nierealny. Podziel pracę i oszacuj. Pokaż ryzyka. Nie zgadzaj się na obniżenie jakości ("Jakoś damy radę - zrobimy bez testów, bez definiowania kryteriów akceptacyjnych, byle działało").
Ustalony termin to nie jest koniec świata i najczęściej można go negocjować, tylko uzbrój się w argumenty, które Ciebie przekonują.
Sam jestem szefem. Nieraz zdarzało mi się chlapnąć jakiś termin, bez większego przemyślenia. Moi pracownicy często się do niego przywiązują - czasami nikomu nie przychodzi do głowy, żeby negocjować przesunięcie terminu. Czasami wystarczy krótka dyskusja i sprawa załatwiona. W tym świecie niemal wszystko jest negocjowalne! Ale często wymaga to odwagi! :) Sprawdźcie - jedną z głównych wartości związanych z Agile'em jest Odwaga. Wiecie dlaczego? :)

Co do trzeciego podpunktu - zacznij używać jakiejś metodyki :) Skorzystaj z pomocy doświadczonego mentora.

środa, 9 lutego 2011

Tagged under:

Kilka nowych koncepcji - Mantra architektoniczna, Design Retrospective, Współdzielony kontekst, Naturalny porządek refaktoryzacji

Ostatnio wyewoluowało mi się w głowie kilka nazwanych koncepcji, a w zasadzie może po prostu je dobrze zrozumiałem :) Kilka notatek poniżej, które traktuje jako alpha draft ;-)

Mantra architektoniczna (ang. architectonic mantra)
To co dzieje się praktycznie w każdym projekcie to dryfowanie architektury, tak że po kilku (nastu) miesiącach trwania projektu mało kto w zespole jest w stanie dobrze określić, jakie operacje powinny być wykonywane np. przez kontroller (lub managedbean lub whatever), jakie przez obiekty dziedzinowe, jakie przez fasady, usługi. Z czasem mieszane są odpowiedzialności tychże klas i coraz trudniej z rozwojem systemu. Jedyną opcją w tym przypadku jest tzw. mantra architektoniczna, która jest wariacją nt. techniki zdartej płyty znanej z psychologii komunikacji. Polega ona na tym, że należy w prace zespołu włączyć ciągłe przypominanie jakie mamy w architekturze główne bloki i jakie są też ich odpowiedzialności. W tym przypadku również sugeruję zespołom, aby wprowadziły regularne spotkania (raz/mc, raz/sprint), które nazywam Design Retrospective podczas których zespół:
a) przypomina mantrę architektoniczną;
b) analizuje sytuacje, w których niejasne jest, gdzie powinny się znaleźć konkretne klasy, operacje, pola - na bazie tego co się działo ostatnio w projekcie
c) zbiera przypadki zdryfowania architektury i tworzy "program naprawczy"
d) podejmuje decyzję o świadomej restrukturyzacji architektury (to akurat rzadziej).

Współdzielony kontekst (ang. shared context)
Nie, nie, nie... bynajmniej nie chodzi tu o żadne wzorce projektowe czy architektoniczne. A o komunikację... Jak to powiedział Kent Beck gdzieś kiedyś "Większość problemów w projektach wynika z tego, że ktoś komuś czegoś nie powiedział". Zwolennicy Agile'a źródło problemów widzą w tzw. relay race, czyli przekazywaniu pracy między ludźmi (pewnie to znacie m. in. w takiej metaforze www.projectcartoon.com/).
Problem polega w tym, że w sytuacji przekazywania produktów (dokumentacji, kodu, wymagań itp.) pracy jednej osoby (grupy osób) innej, nie jest przekazywany kontekst informacji, który doprowadził do powstania tego produktu, często mylnie zakładając, że jest on nieistotny. Ja twierdzę, że jest kluczowy.
Ostatnio uczestniczyłem w takiej sytuacji. Jedna z osób dokonała wstępnej analizy wymagań i stworzyła podstawowy model systemu (model dziedzinowy). Mieliśmy przeanalizować ten model. Jednak nie posiadając kontekstu
(pewne przymyślenia, wnioski, informacje, mikrodecyzje), który powstał w głowie osoby, która go stworzyła dość trudno na głębszym poziomie niż tylko poprawność UMLowa, ocenić poprawność modelu. Taką sytuację nazywam brakiem współdzielonego kontekstu.
Dopiero zaczęliśmy wspólnie analizować wymagania w projekcie (User stories) i wspólnie budować model od nowa. Doszliśmy do podobnego modelu (z kilkoma subtelnymi różnicami), jednak w czasie "wspólnej pracy" powstał współdzielony kontekst (czyli uspójnione przemyślenia i rozumienie tematu). Współdzielony kontekst umożliwia trafniejsze podejmowanie decyzji oraz efektywniejszą kontynuację prac. To dlatego w Agile'u tak duży nacisk kładzie się na ścisłą współpracę - aby budować współdzielony kontekst.
I stąd jedna przestroga: Nie zarzucaj nikogo produktem swojej pracy, będącej efektem wielu godzin działań i/lub przemyśleń, oczekując, że go dobrze zrozumie. Przynajmniej pójdź i razem z nim go (ten produkt) przeanalizuj i wytłumacz jak do tego doszedłeś. A najlepiej wypracowuj to wspólnie :) Oszczędzisz wiele pracy sobie i tej osobie, a w szczególności unikniesz wielu zniekształceń komunikacyjnych (które to właśnie generują bardzo dużo dodatkowej, niepotrzebnej pracy).

Naturalny porządek refaktoryzacji (ang. natural order of refactoring) albo inaczej co to naprawdę znaczy ewolucyjny design lub architektura.
Jest to temat na osobny artykuł, tutaj więc pokrótce.
Od pewnego czasu krystalizuje mi się koncept systematyzacji procesu refaktoryzacji od najniższego poziomu abstrakcji do najwyższego - naturalny sposób na ewolucyjny rozwój designu (projektu systemu).
Idea jest taka - zaczynasz od najprostszego rozwiązania, które następnie refaktoryzujesz (jeśli potrzeba) na różnych poziomach abstrakcji (w pewnym ustalonym porządku). Oto porządek przekształceń (rozpoczynamy od niskopoziomowych).

0. Transformacje (triangulizacje) - jeśli używasz TDD (http://cleancoder.posterous.com/the-transformation-priority-premise)
1. Refaktoryzacje typu
Compose method (http://www.industriallogic.com/xp/refactoring/composeMethod.html) (czyli seria refaktoryzacji typu Extract method)
Czyli pierwszą implementację złożonej metody rozbijam na serię wywołań kilku metod składowych na tym samym poziomie abstrakcji. Z jednego bloku kodu powstaje kilka metod.
2. Refaktoryzacje typu Extract class, Extract interface, Move method, Move field na podstawie analizy odpowiedzialności klasy.
Z czasem wyodrębnionych metod w powyższym kroku jest coraz więcej, więc klasa zaczyna być zbyt duża i często przestaje spełniać regułę SRP (pojedynczej odpowiedzialności). Zatem zaczynasz myśleć o przeniesieniu tychże metod gdzieś indziej. Do innej klasy, do nowej klasy, być może temu będzie towarzyszyć wyodrębnienie się interfejsu, być może będzie trzeba poprzesuwać pola w klasie.
3. Refaktoryzacje do wzorców projektowych (http://www.industriallogic.com/xp/refactoring/)
W sytuacjach, kiedy musisz przygotować się na zmienność w projekcie (np. różne wersje algorytmów, przetwarzanie zdarzeń, adaptowanie struktur czy zachowania), wprowadzasz w projekcie wzorce projektowe.
4. Refaktoryzacja do wzorców architektonicznych (podstawowy opis wzorców http://martinfowler.com/eaaCatalog/)
Z czasem jeśli obecna architektura nie radzi sobie ze zmieniającymi się wymaganiami systemu albo potrzeba innej koncepcji, to modyfikujemy założenia architektoniczne - a zatem również musi ulec zmianie Mantra architektoniczna. Może to być: dodatnie warstwy, usunięcie warstwy, zmiana architektury dziedziny (Domain Model, Active Record, Exposed Domain Model) itp.


Heurystyka zwinnego modelowania systemu (czyli jak zacząć i mieć pewien zgrubny koncept)

Jak dojść zwinnie do wstępnego modelu, który pozwoli ruszyć z implementacją, a jednocześnie pozwoli uniknąć podstawowych błędów związanych z nieprzemyślaną architekturą? Jak i kiedy zaplanować architekturę? Zrobić wstępny projekt w podejściu zwinnym?
Oto propozycja zwinnej "drogi" :) Jest to miks praktyk Scrumowych/Agilowych, ICONIXa i naszych doświadczeń BNSowych.
1. Zdefiniuj (jeśli jeszcze nie masz) User Stories/Epics.
Zazwyczaj wystarczy pokrycie 80% systemu. Pamiętaj, żeby nie przesadzać ze szczegółami. Jeśli twój system ma UI - koniecznie korzystaj z draftów ekranów. Jeśli nie ma przydadzą się uproszczone diagramy określające interakcje systemu. Jakie diagramy? To już zależy od Twojej dziedziny :)
2. Przeanalizuj interakcje z systemami zewnętrznymi. Z nich też będą wynikać US. W efekcie usługi czy elementy modelu.
3. Określ priorytety i zgrubnie określ co wejdzie do Realeasu (wersji wdrożeniowej - czyli zazwyczaj efekt kilku miesięcy prac).
Pamiętaj, najbardziej będą interesować Cię rzeczy o wyższych priorytetach. Te o niższych nie są warte zbyt dużej uwagi.
4. Analizując po kolei User Stories, buduj model dziedziny (docelowo diagram klas dziedzinowych).
Skupiaj się przede wszystkim na nazwach klas i powiązaniach. Jest to najbardziej naturalny słownik dziedzinowy (bardziej definicja nazw).
5. Analizując po kolei User Stories (US), wyodrębniaj usługi (operacje) systemu.
Najlepiej, żeby były sformułowane w języku biznesowym. Na początku nie dziel ich specjalnie. Nawet wrzucaj do wspólnego worka. Dla ułatwienia możesz powiązać je z odpowiednimi US.
6. Określ złożoność operacji.
Określ, które operacje są bardziej złożone (wychodzą poza klasyczny CRUD). Będzie to podstawa do określenia kierunku architektury.
7. Wybierz kierunek architektury (w oparciu o model dziedzinowy)
(m. in. Domain Model, Anemic Domain Model, Active Record, Exposed Domain Model). Uwzględnij technologie, jeśli jest już wybrana lub ją wybierz.
8. Z wyróżnionych usług wybierz te o największym poziomie złożoności i ryzyku w celu analizy.
Zrób proste szkice klas, interakcji, które pozwolą przeanalizować złożoność. Wybieraj tylko te usługi do analizy, które przynależą do US o wysokich priorytetach lub też mogą znacząco wpłynąć na wykonalność projektu.
9. Osadź architekturę w technologii. Spartycjonuj usługi.
Rozrysuj bloki architektury i typowe klasy. Na bazie listy usług - podziel je grupując wg zbliżonych odpowiedzialności (spójnych dziedzinowo).
10. Przeanalizuj 1-2 US (koncept implementacji), które pozwolą zweryfikować założenia koncepcji.
Jeśli weryfikacja się nie powiedzie, wróć do 7 lub 8.
11. Zaimplementuj wybrane 1-2 US, aby zweryfikować koncepcje.
Może to wymagać wstępnego setupu projektu, środowiska. Może to być podstawa to tzw. Iteracji 0, Sprintu 0,
Elaboration phase (?? nie jestem ekspertem RUPa).
Jeśli weryfikacja się nie powiedzie lub koncept ma luki przejdź do 7 lub 8.
12. Zdefiniuj Mantrę architektoniczną.
13. Realizuj inkrementacyjnie projekt (to dalej definiuje metodyka).

Powiązany OFFTOPIC:
Zapodam pewną mądra myśl, która może kogoś natchnie do myślenia:
"W architekturze nie chodzi o rysunki, diagramy, powiązania z innymi systemami, ale o głębokie zrozumienie dziedziny i kontekstu systemu, z którym pracujesz. Zapomnij o UMLu, zapomnij o supernarzędziach wspierających Cię w projektowaniu, włącz myślenie. Włóż najwięcej energii w zrozumienie dziedziny. Ta wiedza już po nitce poprowadzi Cię do odpowiednich konstrukcji projektowych".
Tak, tak, to niewiele mówi. Na razie mogę odesłać do koncepcji Domain Driven Design oraz Lean Architecture (vide: Google).

niedziela, 6 lutego 2011

Tagged under: , , , ,

Nie powinieneś biegać ze złamaną nogą!

Jasne? Oczywiste? Niby tak się wydaje a jednak cały czas biegamy ze złamaną nogą...

Jedną z najczęściej oczekiwanych odpowiedzi, którą chcą usłyszeć osoby(w trakcie szkoleń lub projektów doradczych) - to odpowiedź na pytanie: "Jak mam sobie poradzić z pewnymi problemami w mojej sytuacji" (w moim projekcie, z moim klientem, menedżerem analitykiem whatever...). Jest to oczywiście naturalne pytanie, ale dużo ważniejsze jest pytanie: "Czy sytuacja, w której się znajduję jest zdrowa?". A najczęściej nie jest!
W takiej sytuacji, pierwotne pytanie można porównać do pytania: "Jak mogę szybko i efektywnie biegać ze złamaną nogą?". Chętnie poznam odpowiedzi...

Przykłady:
* Nie mamy dobrego kontaktu z osobą, która definiuje wymagania (bo między nami a klientem jest jeszcze firma pośrednia i dostajemy informacje z drugiej ręki, często nie mamy możliwości bezpośrednio skontaktowania się z taką osobą/osobami).

* Biznes/kierownicy projektu nie uwzględniają technicznych potrzeb podczas ustalania priorytetów (biznesowe priorytety są najważniejsze, ale techniczne nie mogą być ignorowane, gdyż spowoduję nadmierny wzrost kosztów implementacji).

* Nie ma nikogo, kto jest jednoznacznie odpowiedzialny za wymagania, definiuje je i odpowiada za zmiany (ponosi odpowiedzialność za ich koszt). Zazwyczaj odpowiedzialność ta jest rozmyta i wymagania pochodzą z nieskoordynowanych źródeł.

* Brak aktywnego udziału i wsparcia osób biznesowych podczas prac implementacyjnych (trudność w uzyskaniu konkretnych informacji wyjaśniających, jak to dokładnie ma działać).

* Brak refaktoryzacji, bo to kosztuje (za dużo i nikt za to nie zapłaci), bo to nie ma sensu (komu się uda posprzątać ten cały syf?).

* I wiele innych... chyba na każdy z tych tematów można poświęcić osobny artykuł.

Jak w takich sytuacjach zastosować coś rozsądnego? Jak w takim przypadku na przykład zastosować Scrum? (bo w takich sytuacjach najczęściej słyszę tego typu pytanie). Przypomnij sobie podstawowe pytanie: "Jak biegać ze złamaną nogą?"

Zanim zaczniesz dopasowywać się do zaistniałej sytuacji postaraj się wyeliminować z niej patologie! Zazwyczaj tego nie robimy bo:
* jest to trudne,
* często wymaga konfrontacji obecnej rzeczywistości,
* może doprowadzić początkowo do konfliktów i oporu,
* wymaga często dość sporych umiejętności komunikacyjnych (w tym negocjacyjnych),
* często będzie musiało to doprowadzić do zburzenia istniejącego status quo - a tego boi się prawie każdy ...
* zwyczajnie wymaga odwagi!

Więc zazwyczaj uczymy się biegać ze złamaną nogą. Jeeeeeeeeeee.... I like it. Na poziomie lokalnym udaje się wszystko poukładać (jakoś można z tym żyć), na poziomie globalnym jest to bez sensu. A jednak, tak zazwyczaj to funkcjonuje... Ciekawe, nieprawdaż? Niczym w amoku...

Zanim zaczniesz dopasowywać do obecnej sytuacji, krytycznie ją zweryfikuj! Jest pewna mądrość: "Automatyzacja nieprawidłowego procesu (czyli potencjalne jego przyspieszenie) zazwyczaj zwiększa jego nieefektywność". Jeśli sytuacja, w której się znajdujesz jest niezdrowa, czy można znaleźć w tej sytuacji najlepsze praktyki...? Jakie będą najlepsze praktyki biegania ze złamaną nogą? :)

Co zatem robić? To długa odpowiedź, często zależąca od subtelnych niuansów danego kontekstu. Tutaj nawet nie podejmę próby jej sformułowania. Ten post ma sprowokować do myślenia! Jest spora szansa, że jak zaczniesz analizować sytuację (sam/z osobami współpracownikami) - znajdziecie odpowiedzi. Pod warunkiem, że nie będziecie szukać czarodziejskiej różdżki, która bezszelestnie, bezinwazyjnie, bezproblemowo wszystko załatwi. Jeszcze raz przypomnę - próba rozpoczęcia zmian w tym kierunku wymaga ODWAGI i z pewnością wykroczenie poza własną STREFĘ KOMFORTU.

Mały hint. Jeśli w dużym przybliżeniu założymy taki łańcuch (pozwól, że pominę uzasadnienie tego pogrupowania, żeby nie wydłużać posta, może kiedyś będzie okazja...):

programista/tester/grafik... => analityk/kierownik => menedżer/klient/kierownik po stronie klienta

Największą moc sprawczą mają oczywiście ostatnie elementy łańcucha, ale też zazwyczaj im najtrudniej dostrzec patologie, albo też bardzo często są ich źródłem (jako osoby decyzyjne). Tej grupie najłatwiej będzie doprowadzić do potrzebnych zmian.
Najtrudniej mają osoby z początku tego łańcucha (gdyż są najmniej decyzyjne, przez to inicjowane zmiany wymagają często najwięcej odwagi!). Dla nich jedną ze skuteczniejszych (choć często żmudnych i długotrwałych) technik jest technika zdartej płyty :) (czyli ciągłe wskazywanie patologii, pokazywanie ich konsekwencji i upierdliwe o tym przypominanie... niestrudzenie, bez przerwy). Jeśli przy tym uda się zbudować koalicję w naszym łańcuchu, tym większa szansa na zmiany.

Jest jedna opcja - można poszukać pomocy z zewnątrz. Analiza, rekomendacje zewnętrznej niezależnej, obiektywnej osoby/firmy mogą skatalizować proces zmian.

Pamiętaj! Złożenie złamanej nogi może boleć!