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

wtorek, 12 lipca 2011

Tagged under: , , ,

O nazewnictwie słów kilka – metody (in progress)

(Uwaga! Artykuł w trakcie rozwoju!)
Może temat wydaje się banalny i wyświechtany, bo któż nie wie, że trzeba tworzyć jednoznaczne, czytelne nazwy. Natomiast ciągle jest obszar bardzo zaniedbany. Ciągle zespoły są dalekie od zrozumienia, że to właśnie od nazewnictwa zależy najwięcej. Żadna refaktoryzacja nie ma takiej mocy, jak zmiana nazwy. To przede wszystkim nazwy, jeśli stosowane odpowiednio, tworzą tzw. samodokumentujący się kod, kreują jednoznaczny język w źródłach systemu, który tworzysz.
Temat opisany wprawdzie w Clean Code, ale nie tak konkretnie jak ja to widzę, nieco po wierzchu i z innej perspektywy.

Dzisiaj kilka słów o anatomii metody (funkcji). Każda metoda ma tzw. sygnaturę czyli nazwę, parametry oraz zwracany typ, kluczowe składowe z punktu widzenia refaktoryzacji, gdyż na czytelność składają się wszystkie trzy elementy – nie tylko nazwa.
Ponadto można powiedzieć, że są dwa rodzaje metod:
• zwracające wynik;
• niezwracające wynik.
Metody zwracające wynik
(Uwaga! Poniższe zasady nie dotyczą tzw. interfejsów typu fluent)
 
double computeSomeResult(int parameter1, double parameter2, int parameter3 …)
 
• nazwa metody zawsze konkretnie i jednoznacznie musi określać, czym dana metoda się zajmuje i musi z niej wynikać, co będzie jej wynikiem;
• sygnaturę metody twórz zawsze w kontekście klasy, w której się znajduje (nie powtarzaj nazwy klasy w nazwie metody);
• tym samym metody zwracające informacje o błędach powstałych podczas jej wykonania są antywzorcem (choć oczywiście jest śladowa liczba przypadków, kiedy taka strategia może być uzasadniona – zazwyczaj gdy pracujemy z kodem odziedziczonym); tej chorobie ulega wiele frameworków;
• wysoce karalne jest traktowanie parametrów wejściowych jako sposób na zwracanie wyniku, co najczęściej dzieje się w przypadku opisanym w punkcie powyżej;
• parametry metody współtworzą znaczenie z nazwą – muszą ją uzupełniać i być z nią zgodne.
Przykłady i komentarze
1)

 
List<Content> retrieveChildren(Content parentContent)  
 

Ok! Nazwa sugeruje, że będą wyszukiwane dzieci parametru i taki też jest zwrócony typ.
Bardziej fluentowe wersje (TBD wyjaśnić co to):

 
List<Content> retrieveChildrenOf(Content parentContent)  
List<Content> childrenOf(Content parentContent)
 
Lub jeśli byłoby to adekwatne do kontekstu, metoda childrenOf mogłaby być składową klasy Content i wtedy jej sygnatura wyglądałaby:
 
class Content {
   List<Content> retrieveChildren() // ..
   // lub bardziej fluentowo
   List<Content> children() // ..
}
 
2)
 
interface ContentProcessorResolver {
   //…
   /* @return zwraca listę treści dostosowaną do danego resolwera */
   public List<? extends Content> resolve(Content content);
   //…
}
 
Zła nazwa – sugerowałaby (w kontekście interfejsu, w którym się znajduje), że wynikiem będzie obiekt klasy ContentProcessor.

TBC…

wtorek, 5 lipca 2011

Tagged under: , , , , ,

Implementacja - Proste wprowadzenie do BDD cz. 3

JBehave, Behaviour-Driven Development (BDD) ciąg dalszy, tym razem już implementujemy... i kilka ciekawych ficzerów narzędzia...

Have fun!