Jul 13 2010

Test Driven Development

Chciałbym popełnić kilka artykułów na temat Agile, ale zanim to zrobię, chcę wyjaśnić na czym polega Test Driven Development (TDD), które jest ściśle powiązane z tą metodologią.

Test Driven Development – ogólny przegląd

Programowanie oparte na testach (bo tak to można przetłumaczyć) różni się od tradycyjnego, że testy pisane są przed kodem. Ciężko to zrozumieć zanim się tego nie zrobi, a jeszcze ciężej zrozumieć, że ta metoda na prawdę działa.
Otóż zanim weźmiemy się za programowanie jakieś funkcjonalności najpierw piszemy do niej test. Gdy go uruchomimy – wiadomo – oznaczony zostanie kolorem czerwonym jako błędny.
Drugim krokiem jest napisanie “tak mało kodu jak to tylko możliwe, jednak wystarczająco, aby test przeszedł. Trzecim ostatnim krokiem, jest poprawienie kodu (zarówno programu jak i testu) aby zwiększyć jego czytelność i funkcjonalność, nie psując przy tym testu. Trzeci krok nie jest obowiązkowy. Metodologia ta mówi także, że ten proces nie powinien zająć mniej niż 10 minut.

Proces taki często nazywany jest Red-Green-Refactor i może być zobrazowany np. w ten sposób:
Red_Green_Refactor

Podczas refactoringu musimy uruchamiać testy od czasu do czasu, aby sprawdzać czy nadal są one zielone.

Jeżeli dobrze będziemy używać TDD to przyniesie nam to bardzo dużo dobrego. Przede wszystkim, nasz program będzie dobrze pokryty testami, powinniśmy się starać tak pisać testy, aby pokryć każdą linijkę kodu. Drugą zaletą jest zasada YAGNI (You Ain’t Gonna Need It), pisząc kod nie powinniśmy dodawać funkcjonalności, które nie są nam w tej chwili potrzebne. Osobiście ciężko mi było przestawić się ten rodzaj programowania. Zawsze miałem “wizję” całego programu przed oczami i gdy pisałem coś nowego miałem na uwadze funkcjonalności z końca projektu. Czasami głowa bolała od tego wszystkiego, gdy zacząłem się gubić co i gdzie ma być. Zgodnie z YAGNI nie myślę co będzie “potem” skupiam się na “teraz”, bo pracując wg metodologi Agile, może się okazać, że “potem” będzie zupełnie inne niż zdaje się być.
Opisując zasadę YAGNI można jeszcze zwrócić uwagę na kilka ważnych rzeczy. Kod pisany nad wyrost może znacznie podnieść ryzyko niepowodzenia projektu. Dopisując coś, co tak na prawdę w tej chwili jest zbędne musimy to brać pod uwagę przy pisaniu ważnych rzeczy. Możemy nieświadomie wprowadzić ograniczenia, które staną na przeszkodzie terminowemu ukończeniu projektu. Najczęstszym błędem jest myśl “Tylko dopiszę trzy linijki”. Potem 3 kolejne do tych trzech i tak lawinowo napiszemy kawał kodu, który musimy dodatkowo udokumentować i otestować.

W TDD testy stają się integralną częścią systemu a nie istnieją jedynie jako dodatek do niego.

Jak powinno wyglądać TDD

Mamy na prawdę dużo narzędzi, aby testy były wykonywane automatycznie. Szkoda czasu na ręczne uruchamianie ich. Wiele też środowisk programistycznych posiada narzędzia wspomagające testowanie.

1. Pierwszym krokiem jest przygotowanie listy funkcjonalności, które zamierzamy napisać. Lista taka jest przeważnie utworzona w jakiś zewnętrznym narzędziu do prowadzenia projektów.
2. Piszemy test – zgodnie z powyższymi wytycznymi. Test sprawdzający jedną funkcjonalność.
3. Piszemy kod – który spowoduje pomyślnie ukończenie testu – piszemy tylko tyle ile trzeba.
4. Gdy jest taka potrzeba poprawiamy kod programu i kod testów. Testy nadal muszą być zielone.
Cały czas pamiętajmy o 10 minutowym cyklu.

Jakieś rady?

Testy możemy pisać w dowolnej kolejności, nie są uzależnione jeden od drugiego. Pamiętajmy tylko aby był on nieduży. Gdy test nam trochę “urośnie” to podzielmy go na jeden lub dwa. Dobrą praktyką jest nie nadużywanie dysku twardego lub bazy danych. Tam gdzie to jest możliwe, w ogóle z tego nie korzystajmy. Twórzmy obiekty w pamięci, chyba że specyfika testu akurat będzie wymagać dostępu do innego medium.

Problemem jednak mogą być sytuacje gdy jedna klasa jest powiązana bezpośrednio z drugą. Nie powinniśmy testować dwu klas na raz NIGDY. Aby tego uniknąć stworzono dwa sztuczne, puste obiekty testowe. Pierwszym z nich jest stub. Stuby są obiektami, których stanem sterujemy ręcznie. Nie posiadają one żadnej logiki obliczeniowej. Gdy Stub ma zwracać jakąś wartość – to musimy sami ustalić jaką. Użycie stubów przeważnie jest wykorzystywane tylko po to aby aplikacja się kompilowała.
Drugim sztucznym obiektem jest mock. Obiekty typu mock z kolei, służą do testowania funkcjonalności. Sprawdzamy za ich pomocą działanie wywoływanych metod. Opisywanie mocków to jest temat na długi artykuł więc pozostanę na takim opisie. Dodam tylko jeszcze to:
- Stub jest obiektem zawierającym informacje o stanie faktycznym, pożądanym lub końcowym. Służy zatem do testowania stanu.
- Mock jest obiektem zawierającym informacje o zachowaniu i sposobie dotarcia do stanu końcowego. Służy zatem do testowania zachowania.

Nie wszystko testujemy

Pisząc pierwsze w swoim życiu testy, zastanawiamy się co testować, a czego nie? Dla początkującego może to być poważny problem, aby nie tracić czasu na zbędne testy.
Główną zasadą jest to, że testujemy każde miejsce zagrożone błędem – wszystko to co jest podejrzane o zagrożenie w działaniu. Przypuszczam, że po pewnym czasie intuicja dokładnie nam podpowie co testować a co nie.

Czego nie testować?

Nie testujemy przede wszystkim obcego kodu. Jeżeli w projekcie wykorzystujemy obcą bibliotekę, to jej nie testujemy. Testy piszemy tylko i wyłącznie do własnego kodu. Nie testujemy także getterów i setterów oraz metody toString() (w javie), chyba że metody te mają jakąś dodatkową funkcjonalność. Nie testujemy także głównej biblioteki języka. Istnieje także szkoła, która mówi, że nie testujemy metod prywatnych ponieważ są one testowane przy okazji metod publicznych. Tak i nie. Ale powinniśmy sami dojść do tego czy powinniśmy takie metody testować czy nie. Może to zależeć w szczególności od języka i od specyfiki projektu. Uważam, że w niektórych przypadkach metody prywatne także powinny zostać przetestowane.

Problemy z TDD

Przy niektórych aplikacjach możemy napotkać problemy z pisaniem testów. Testowanie niektórych funkcjonalności może być bardzo trudne, np.:
- testowanie na danych w bazie danych,
- testowanie aplikacji wielowątkowych,
- testowanie Interfejsu Użytkownika,
- testowanie aplikacji uruchamianych w oddzielnych kontenerach (JSF, Portlets),

W takich sytuacjach powinniśmy sami zdecydować co jesteśmy w stanie poświęcić:
- bezpieczeństwo – nie poświęcając zbyt dużej ilości czasu na te skomplikowane testy,
- czas – pisząc te testy.

Reasume

Mam nadzieję, że ten pokrótce przedstawiony temat zachęci do testowania swojej aplikacji w większym stopniu. Albo chociaż zachęci do zapoznania się bardziej szczegółowo z tematem TDD.

  • Wykop
  • Blip
  • Twitter
  • Facebook
  • DZone
  • Digg
  • Blinklist
  • Delicious
  • Evernote
  • LinkedIn
  • Google Bookmarks
  • Google Buzz
  • Google Reader
  • Share/Bookmark

Jun 1 2010

To że Windows jest…

dziurawy, to wie chyba każdy, kto interesuje się chociaż trochę bezpieczeństwem komputerów. Jednak dzisiaj potwierdziła to jedna z największych firm informatycznych świata – Google. Po ostatnich atakach chińskich hakerów na komputery stacjonarne pracowników firmy, zdecydowali oni, na całkowite porzucenie tego systemu operacyjnego. Do tej pory pracownicy Google mogli wybrać system operacyjny, na którym chcą pracować: Windows, Mac OSX albo Linux. Obecnie zostały do wyboru tylko dwa – pracownicy mogą przenieść się na platformę firmy z Cuppertino, albo na ich PC’tach zostanie zainstalowany Linux.

Oczywiście istnieje możliwość pozostania przy Windows, ale musi to być bardzo mocno argumentowane i zatwierdzone przez dyrektora działu informatyki.

Żródło: Fortune

  • Wykop
  • Blip
  • Twitter
  • Facebook
  • DZone
  • Digg
  • Blinklist
  • Delicious
  • Evernote
  • LinkedIn
  • Google Bookmarks
  • Google Buzz
  • Google Reader
  • Share/Bookmark

Nov 4 2009

Mysql i Snow Leopard

Po aktualizacji systemu do MacOS X 10.6 (Snow Leopard) zauważyłem, że nie startuje moja baza danych Mysql. Sprawdziłem ręcznie co jest nie tak:

cd /Library/StartupItems/MySQLCOM
sudo ./MySQLCOM start
Could not find MySQL startup script!


aha! Poszedłem więc do /usr/local i zrobiłem link symboliczny
sudo ln -s mysql* mysql
Po ponownej próbie uruchomienia bazy danych otrzymałem komunikat:
Starting MySQL database server
Czyli wszystko ok.

  • Wykop
  • Blip
  • Twitter
  • Facebook
  • DZone
  • Digg
  • Blinklist
  • Delicious
  • Evernote
  • LinkedIn
  • Google Bookmarks
  • Google Buzz
  • Google Reader
  • Share/Bookmark

May 4 2009

Matura

Żwawy żuczek z żółtym brzuchem żwawo z życiem
żuł rzeżuchę. Wtem żółw, drobiąc nóżką,
bieży po żywności zapas świeży. Żuczku, żaczku,
żwawe dziecię, zmykaj chyżo, bo żółw zje cię.
Żuk już żagle chciał rozpostrzeć, gdy marudę żółwia
spostrzegł, co wysiłek czyniąc duży, żmudnie
grzebał się w kałuży. Zżarł rzeżuchę żuk niecnota,
a żółw grzebie się wśród błota.

Dziś matury – tradycyjnie rozpoczynają się od języka polskiego. Jak sobie przypomnę, że od mojej minęło już 13 lat…. ;) .

Wszystkim maturzystom, życzę połamania piór.

  • Wykop
  • Blip
  • Twitter
  • Facebook
  • DZone
  • Digg
  • Blinklist
  • Delicious
  • Evernote
  • LinkedIn
  • Google Bookmarks
  • Google Buzz
  • Google Reader
  • Share/Bookmark

Apr 1 2009

Prima Aprilis w IntelliJ IDEA

Dzisiaj podczas pisania kodu w JSF, po użyciu często używanego skrótu podpowiadającego składnię zauważyłem coś dziwnego. Poza standardową listą atrybutów możliwych do użycia zobaczyłem na końcu listy napis: “Don’t be lazy, type it yourself”.

screen2Nieźle się uśmiałem. Zacząłem ostro klikać Ctrl+Space i poczytałem sobie więcej takich perełek, np.

“Just relax”

“Not so fast”

“Are you sure?”

“Don’t panic”

“And why did you do that?”

“Code completition might be insuitable for children under 7″

“Please type slower, I can’t keep up with you”

i wiele wiele innych :)

  • Wykop
  • Blip
  • Twitter
  • Facebook
  • DZone
  • Digg
  • Blinklist
  • Delicious
  • Evernote
  • LinkedIn
  • Google Bookmarks
  • Google Buzz
  • Google Reader
  • Share/Bookmark

Mar 9 2009

Confused with Ranges

Fajną nowością w języku Groovy, w porównianiu do języka Java są Ranges. Jest to kolekcja ( a dokładnie wyjasniając implementuje interfejs java.util.List ), która definiuje zasięg kolekcji – początek i koniec. Oznacza się go oddzielajac dwoma kropkami pierwszy element od ostatniego, np. 1..3 zawiera kolekcję liczb od 1 do 3 (włącznie), a 1..<3 zawiera kolekcję liczb od 1 do 3 (nie wliczając 3). Problem jest właśnie ze zrozumieniem jak działa ten znak miejszości.

Mamy na przykład w kodzie tablicę:

 1 def a = ['a', 'b', 'c', 'd', 'e']

Elementy posiadają indeksy od 0 do 4, jednak w groovym dodatkowo posiadają indeksy od -5 do -1 .

   a  b  c  d  e
   0  1  2  3  4
  -5 -4 -3 -2 -1

Dodatkowe indexy służą m.in. do pobierania elementów tablicy od końca.

 1 assert a[0] == 'a'
 2 assert a[-5] == 'a'

Możemy pobierać elementy tablicy za pomocą Range:

 1 assert a[0..3] == ['a', 'b', 'c', 'd']

lub w odwrotnej kolejności:

 1 assert a[-1..-5] == ['e', 'd', 'c', 'b', 'a']

Teraz porównywanie ‘do’:

 1 assert a[0..<3] == ['a', 'b', 'c']

nie wlicza 3 do zasięgu, więc są wypisane elementy o indeksach 0, 1 i 2.
Jak to się ma przy indeksach ujemnych? Sprawdźmy:

 1 assert a[-5..<-3] == ['a', 'b']

zasięg bierze indeksy DO 3 więc zaczynając od pierwszego -5 na -4 kończy. Czyli wszystko tak jak powinno.

Teraz zagadka:

biorąc pod uwagę, że elementy tablicy posiadają indeksy tak jak wyżej podano:

   a  b  c  d  e
   0  1  2  3  4
  -5 -4 -3 -2 -1

Które elementy posiada subtablica a[0..<-3] ?

Logicznie rzecz biorąc index mniejszy od -3 = -4 . więc subtablica powinna zwierać elementy ‘a’ (index początkowy 0) i ‘b’ (indeks -4). Jednak wynik jest inny:

 1 assert a[0..<-3] == ['a', 'b', 'c', 'd']

Jak to interpretować? Otóż we wszystkich podanych wyżej (oprócz ostatniego) przykładach początek zasięgu był mniejszy od końca ( a < b ). W ostatnim, początek jest większy od końca ( 0 > -3). Groovy zatem interpretuje taki zasięg jako odwrotny i znak mniejszości faktycznie również odwraca i traktuje jako znak większości. Czyli w powyższym przykładzie podaje jako koniec zasięgu index większy od -3 czyli -2. Z tego powodu mamy taki wynik.

Tak samo będzie w przypadku:

 1 assert a[4..<1]  == ['e', 'd', 'c']
  • Wykop
  • Blip
  • Twitter
  • Facebook
  • DZone
  • Digg
  • Blinklist
  • Delicious
  • Evernote
  • LinkedIn
  • Google Bookmarks
  • Google Buzz
  • Google Reader
  • Share/Bookmark

Feb 28 2009

dobry kod – na skróty

Każdy kiedyś uczył się pisać. Najpierw rysując szlaczki aby opanować kontrolę nad dłonią, potem literka za literką cały alfabet. Gdy już się nauczyliśmy – charakter pisma wyrabiał się wraz z ilością zapisanego tekstu. Jednak niektórzy starali stawiać równe, okrągłe literki, starali się robić równe odstępy między wyrazami. Tak długo, aż mieli ładny, czytelny charakter pisma. Ale nie wszyscy się starają – większość pisze tak jak leci.

Tak samo jest z programistami. Gdy nauczą się podstaw programowania – nabierają doświadczenia poprzez pisanie programów i…. to wszystko. Pisanie programów w stylu: „ważne, że działa” i doświadczenie jedynie poprzez własnoręcznie napisany kod. Ale nie każdy taki jest. Niektórzy chcą pisać dobry kod – starają się, uczą nowych rzeczy, analizują inne programy, aby zobaczyć jak piszą inni. Dążą do pisania kodu w jak najlepszym stylu.

Jak jednak wygląda dobry kod? Jak się go pisze? Czterowersem z rymem naprzemiennym?

Jak można ocenić, że kod jest dobry?

Przez tyle lat gdy na świecie są komputery narodziło się mnóstwo autorytetów z dziedziny programowania. Powstały też kanony, standardy i przede wszystkim dobre style programowania. Po tych wszystkich latach można także ocenić który kod jest dobrze napisany.

Przede wszystkim program powinien być bardziej przemyślany niż napisany. Czym więcej czasu poświęcimy na projektowanie i analizę, tym więcej czasu zaoszczędzimy na programowaniu.

Przed przystąpieniem do pracy na programem powinniśmy wiedzieć co, gdzie i jak powinno w programie funkcjonować. Które klasy powinny znaleźć się w programie, co powinny wykonywać i jak się nazywać, a także z którymi innymi klasami powinny być połączone.

Na samym początku powinniśmy zadać sobie pytanie CO ten program (lub pojedynczy moduł programu) powinien robić lub CZYM powinien być. Musimy się zastanowić jakie warunki program musi spełniać aby dobrze działał – czyli wykonywał to co powinien. Pamiętaj: niezależnie gdzie pracujesz, jakie oprogramowanie tworzysz oraz jakiego języka programowania używasz – jednego możesz być pewien: wymagania się zmieniają. Dobrze napisany program pozwoli nam na szybkie zmodyfikowanie i dostosowanie programu do nowych wymagań.

Powinniśmy napisać przypadki użycia. Są to napisane krok po kroku działania programu. Może to bardzo pomóc przy projektowaniu programu. Analizując później tak sporządzony przypadek użycia – możemy rzeczowniki w nim użyte uznać jako klasy a czasowniki jako metody.

Nazwy klas powinny jednoznacznie wskazywać czym klasa jest, a nazwy metod – jakie czynności wykonują. Każdy obiekt reprezentuje jedno pojęcie (przynajmniej powinien). Nie używa się obiektów realizujących dwa lub więcej obowiązków. Jeżeli przeglądając właściwości obiektu znajdujemy właściwości o wartości null lub w ogóle nie wykorzystywane, to może oznaczać, że obiekt pełni kilka ról. Jeżeli takie właściwości istnieją, a jesteśmy pewni, że obiekt pełni tylko jedną rolę w systemie to nieużywane właściwości powinniśmy wywalić do oddzielnej klasy. Cały kod który może ulec zmianie oddzielamy od tego który nie ulegnie zmianie. Takie działanie nazywa się hermetyzacją.

Jeżeli wydzielimy to, co może się zmienić, a potem faktycznie się zmieni – a zmiany które to spowoduje będziemy musieli dokonać w klasach innych niż wyodrębniona – to oznacza, że hermetyzacja jest źle wykonana.

Obiekt powinien mieć tylko jedno zadanie a wszystkie usługi powinny się koncentrować na jego realizacji. Bardzo łatwo sprawdzić czy ta zasada jest zachowana. Wystarczy dla każdej metody utworzyć zdanie gdzie nazwa metody jest czasownikiem, nazwa klasy podmiotem a obiekty podane jako parametry metody mogą służyć jako dodatkowe rzeczowniki (chyba że parametr jest nieistotny bo np. tylko zmienia ilość lub szyk). Gdy metoda jest bez parametrów dodajemy „się”(może być w domyśle, chodzi o to, że metoda wykonuje czynność na samym sobie). Jeżeli utworzone w ten sposób zdanie łamie sens jego rzeczywistego odpowiednika to zasada jednej odpowiedzialności jest złamana. Np. klasa Obiad posiadająca metody: liczbaKalorii(), podajSkład(), ugotuj(). Porównując klasę do rzeczywistego obiektu obiad wiemy, że obiad jest w stanie podać SWOJĄ liczbę kalorii albo SWÓJ skład, ale SAM SIĘ NIE ugotuje. Więc metoda ugotuj() łamie tę zasadę. Obiad gotuje kucharz, czyli Kucharz.ugotuj(Obiad).

Analiza ta jednak w dużej mierze zależy od znajomości systemu. Np. w powyższym przykładzie metody Kucharz.ugotuj(Obiad) jest zgodna z zasadą jednej odpowiedzialności. A metoda Kucharz.ugotuj()? Czy jest zgodna? Na pierwszy rzut oka nie jest. Nie ma logicznego sensu aby kucharz SAM SIEBIE gotował. Jednak system może być zaprojektowany tak, że każdy obiad ma swojego kucharza i obiekt Obiad jest przekazywana obiektowi Kucharz jako parametr konstruktora. Zatem metoda ugotuj() wie, którego Obiadu użyć i nie potrzebuje go jako parametru. Mając tą wiedzę – czy dalej twierdzimy, że metoda Kucharz.ugotuj() łamie zasadę jednej odpowiedzialności? Pamiętaj, że ocena o odpowiednim stosowaniu zasad ( lub ich łamaniu) jest wysoce zależna od znajomości systemu.

W naszym programie powinniśmy także odpowiednio zadbać o relacje między klasami. Rodzajów tychże nie ma dużo: dziedziczenie, implementacja lub asocjacja.

Z dziedziczeniem jest pewien problem. Dziedziczenie (czy też zgodnie z UML – generalizacja) powinno być wykonane w ten sposób aby była możliwość podstawienia typów pochodnych w miejsce ich typów bazowych (Zasada paradygmatu Liskov’a). Dziedziczenie w celu rozszerzenia funkcjonalności niesie za sobą ryzyko, że klasy pochodne nie będą potrzebne do ich działania i nie będą potrafiły tych metod zaadoptować. W takich sytuacjach należy poszukać innych rozwiązań, np. delegacja(jedna z grupy asoocjacji) lub kompozycja.

Kompozycja to jest używanie interfejsów. Z tym, że nie chodzi tylko o słowo kluczowe interface ale także klasy abstrakcyjne. Kompozycja pozwala stosować zachowanie udostępnione przez rodzinę innych klas i zmieniać to zachowanie w trakcie działania. Określamy w obiekcie, którym interfejsem jesteśmy zainteresowani (który realizuje niezbędne operacje) a w jego miejsce podsyłać klasy, które ten interfejs implementują. Stosują kompozycję nie jesteśmy uzależnieni od konkretnej implementacji. Kod jest elastyczny na rozszerzanie bo można utworzyć nową klasę o tym interfejsie i ją podstawić. Używając interfejsów a nie klas które je implementują pozwoli na napisanie kodu dla klas, które nawet jeszcze nie istnieją. Kompozycja jest dobrym sposobem aby program był otwarty na rozszerzanie i podatny na zmiany, co jest bardzo ważne: powinniśmy starać się powodować aby raz napisany kod nie był modyfikowany. Jednocześnie napisać go tak aby szło go rozszerzyć, jeżeli nie przez kompozycję to np. przez dziedziczenie.

Nie ma lepszego sposobu na sprawdzenie czy pogram jest odporny na zmiany niż sama zmiana.

Innym typem relacji jest asocjacja, która oznacza zależność jednej klasy od drugiej. Utworzenie obiektu klasy A w obiekcie klasy B jest asocjacją. Są dwa główne rodzaje asocjacji: delegacja i agregacja. W delegacji obiekt który ma wykonać pewną czynność nie wykonuje jej, ale przekazuje jej wykonanie do innej klasy. W agregacji jeden obiekt jest częścią drugiego, np. obiekt Adres jest częścią obiektu Pracownik.

Częstym problemem jest nie odróżnienie kiedy używać agregacji a kiedy kompozycji. Agregację wykorzystujemy wtedy, gdy obiekt agregowany istnieje poza obiektem agregującym, jako oddzielny byt. Jeżeli obiekt agregowany nie musi mieć własnego bytu – używamy kompozycji.

Kolejną ważną zasadą jest unikanie powtarzania kodu. Najłatwiej tego dokonać poprzez wyodrębnienie wspólnych fragmentów i umieszczenie ich w jednym miejscu. Czyni to kod łatwiejszym w utrzymaniu i przy ewentualnych zmianach. Chodzi tu także o to, aby nie powtarzać funkcjonalności w kilku miejscach. W takim przypadku trzeba przenieść kod dotyczący tej funkcjonalności w jedno miejsce. Jednym słowem: należy się starać, aby każda informacja i operacja była tylko w jednym miejscu.

Pracując z dużym programem koncentruj się tylko na jednej możliwości naraz. Nie pozwól się zdekoncentrować i nie zajmuj się innymi możliwościami. Najpierw należy się skupiać na głównych funkcjonalnościach programu. Potem – wchodząc w głąb – programujemy kolejne funkcjonalności jedną po drugiej tak długo, aż będą napisane wszystkie z tego poziomu. Potem piszemy bardziej szczegółowe i tak dalej.

Drugą szkołą jest skupianie się na przypadkach użycia. Tworzymy scenariusz przejścia przez aplikację i piszemy kod aby ten scenariusz obsłużyć. Potem kolejny (inny) scenariusz i kod. Tak długo aż scenariuszami opiszemy wszystkie funkcjonalności programu.

Opanowanie tych zasad pomoże zaznajomienie się z wzorcami projektowymi – co i moim zdaniem jest wielce zalecane.

Mam nadzieję, że teraz pisany kod będzie prześliczny a jeszcze bardziej elastyczny :D – po prostu dobry kod.

  • Wykop
  • Blip
  • Twitter
  • Facebook
  • DZone
  • Digg
  • Blinklist
  • Delicious
  • Evernote
  • LinkedIn
  • Google Bookmarks
  • Google Buzz
  • Google Reader
  • Share/Bookmark

Jan 13 2009

Plany na rok 2009

Zeszłoroczne plany zrealizowałem z około 70%, więc nie jest tak źle. Na ten rok też sobie kilka rzeczy postanowiłem i będę dążył do ich realizacji. Z zawodowych planów na pierwszym miejscu są Design Patterns i TestNG. Chcę pisać czysty kod i pokrywać go testami co najmniej w 90% ( o ile się da oczywiście). Będzie to mój osobisty wkład w rozwój umiejętności programowania. Jeżeli zostanie trochę czasu (którego i tak mam mało :D )- zajmę się Groovy’m no i może uda się w tym roku zdać SCJP? Zobaczymy… Dwa pozostałe cele pozostaną w tajemnicy. Chciałbym także zrealizować chociaż jeden ze swoich projektów… Zobaczymy co nam ten rok przyniesie.

  • Wykop
  • Blip
  • Twitter
  • Facebook
  • DZone
  • Digg
  • Blinklist
  • Delicious
  • Evernote
  • LinkedIn
  • Google Bookmarks
  • Google Buzz
  • Google Reader
  • Share/Bookmark

Aug 21 2008

Złota myśl dnia

W teorii nie ma żadnej różnicy między teorią a praktyką – w praktyce jest.

  • Wykop
  • Blip
  • Twitter
  • Facebook
  • DZone
  • Digg
  • Blinklist
  • Delicious
  • Evernote
  • LinkedIn
  • Google Bookmarks
  • Google Buzz
  • Google Reader
  • Share/Bookmark