Jesień w wielu firmach sprzyja przeprowadzaniu tak zwanych ocen rocznych. W zależności od organizacji przypominają one albo bardziej pospolite ruszenie, albo też są częścią większej całości i feedbacków dostarczanych systematycznie przez cały rok. Niezmiennie jednak to managerowi projektu przypada zazwyczaj rola osoby odpowiedzialnej za przygotowanie oceny.
Tutaj niejednokrotnie w naszych głowach pojawia się pytanie- „Co to znaczy DOBRZE ocenić programistę?”.
Niektóre firmy mają zdefiniowane kryteria, według których taka ocena przebiega. Należą do nich przede wszystkim:
- Kompetencje techniczne, a więc znajomość inżynierii oprogramowania, bibliotek i frameworków, wzorców projektowych, technik testowania itp.
- Organizacja czasu, terminowość oraz strukturyzacja własnej pracy
- Komunikatywność
- Umiejętności prezentacyjne…
…oraz wiele, wiele innych. Każdy z tych aspektów jest niewątpliwie bardzo ważny. Dobry specjalista zna się na swojej dziedzinie. W tym więc przypadku oczekujemy od programisty, że będzie wiedział, jak pisać dobry jakościowo kod. Dodatkowo ze względu na pracę zespołową chcemy, aby potrafił skutecznie komunikować się z innymi, a także, by prezentował wyniki swojej pracy. Czy jednak to już wszystko? Co tak naprawdę w przypadku programowania znaczy dobre wykonywanie swoich zadań?
Dobre wykonywanie swoich zadań
W trakcie feedbacku często możemy usłyszeć stwierdzenie „Wykonujesz swoje zadania dobrze” lub też przeciwnie „Nie zawsze wykonujesz swoje zadania poprawnie”. Co jednak należy pod tą opinią rozumieć?
Zapewne osoba wypowiadająca te słowa ma na myśli realizację zadania zgodnie z opisem w User Story tudzież z dokumentacją, w zależności od tego, w jakiej metodologii pracujemy. Dla niewtajemniczonych w Scruma User Story możemy traktować jak zadanie związane z określoną funkcjonalnością i posiadające swoje kryteria akceptacyjne. Dzięki temu wszystkie wymagania (inaczej acceptance criteria) zadania są spełnione, funkcjonalność działa, a klient otrzymuje wartość, której oczekiwał.
Myślimy jednak tutaj także o odpowiednim otestowaniu funkcjonalności testami jednostkowymi, tak aby pokrycie kodu było na odpowiednim poziomie (zazwyczaj powyżej 80%). Więcej o zagadnieniu testowania w projekcie przeczytacie w osobnym wpisie explicit na ten temat, który już w kolejnych tygodniach pojawi się na blogu.
Idąc dalej należałoby się zastanowić nad czystością samego rozwiązania. Myślimy tutaj o tym, czy pisany kod jest w odpowiedni sposób strukturyzowany, czy jest podzielony we właściwy sposób architektonicznie. Odpowiada to między innymi możliwości wprowadzenie w przyszłości zmian bez konieczności przepisywania większości funkcjonalności na nowo. Tutaj pojawiać się będą również takie zasady jak pojedyncza odpowiedzialność (ang. single responsibility), a także wykorzystanie wzorców projektowych. Jeśli nie spotkaliście się jeszcze z tym pojęciem, wzorce dostarczają nam propozycje rozwiązań dla najbardziej popularnych problemów programistycznych.
Nawet jeśli dostarczany przez programistę kod spełnia swoje zadanie pod względem funkcjonalnym, jest przetestowany i dobrze zaprojektowany, pozostaje jeszcze aspekt organizacyjny- znajomość procesu wytwarzania oprogramowania lub innymi słowy znajomość procesu SE (ang. Software Engineering). Co należy pod tym pojęciem rozumieć? Oprogramowanie wytwarzamy zespołowo, według dobrych praktyk i przyjętych reguł. Tutaj zastanawiamy się, czy:
- programista wie, jak prawidłowo korzystać z repozytorium
- przestrzega procesu code review i mergowania
- współpracuje z testerami w kontekście testów manualnych i automatycznych jego funkcjonalności
- współpracuje z grafikami odnośnie design review
- potrafi doprecyzować funkcjonalne i niefunkcjonalne wymagania
- jest w stanie wyszacować nakład pracy związany z danymi zadaniem w sposób zbliżony do rzeczywistości
- potrafi przewidzieć konsekwencje zastosowania wybranego rozwiązania programistycznego
Oczywiście nie są to wszystkie aspekty, natomiast, aby dokładnie omówić proces wytwarzania oprogramowania całościowo, potrzebowalibyśmy zdecydowanie więcej czasu.
Czego zazwyczaj nie znajdziesz w pytaniach pomocniczych i formularzach do oceny?
Istnieje kilka punktów, które ja osobiście uważam za bardzo ważne i zawsze zwracam na nie szczególną uwagę. Dlaczego? Ponieważ nie są to punkty oczywiste, szczególnie u młodszych stażem programistów. Ponadto to właśnie te cechy stanowią w mojej opinii różnicę pomiędzy programistą poprawnym a naprawdę dobrym.
Patrzy szerzej.
Bardzo dobrzy programiści nie koncentrują się tylko i włącznie na swoim zadaniu. Zastanawiają się, jak właśnie dodany kod, który spełnia wymogi ich User Story, wpłynie na całość aplikacji. Czy po tych zmianach ta aplikacja nadal będzie spójna, czy być może dodanie tej funkcjonalności niesie również ryzyko dla innych części aplikacji? Co należy sprawdzić i potencjalnie również uwzględnić w implementacji? Czy zastany sposób implementacji jest słuszny, czy być może należałoby jeszcze jakoś go ulepszyć, lekko zmienić, dzięki czemu końcowa implementacja nie wyglądałaby jak stare rozwiązanie z dodanym obejściem dla szczegółowych przypadków?
To podejście jest bardzo bliskie zasadzie skauta przytoczonej w książce Clean Code wujka Boba, a więc Roberta C. Martina. Zasada ta w tłumaczeniu na język polski brzmi następująco:
Zawsze zostawiaj obóz czystszy, niż go zastałeś.
Jest to bardzo dumna reguła, która stosowana na co dzień prowadzi do znaczącego wzrostu jakości kodu.
Jest odważny i szczery.
Odwaga i szczerość pozwalają na podejmowanie się tematów i problemów, których jeszcze dobrze nie znamy lub nie umiemy. Dzięki temu dużo szybciej się uczymy, rozszerzamy nasze umiejętności. Rośnie również nasza pewność siebie, gdyż udowadniamy sami sobie, że potrafimy odważnie stawiać czoła wyzwaniom. Takie osoby są także bardzo cenne dla projektu, gdyż z jednej strony nie boją się podjąć tematów trudnych, a z drugiej są w stanie szczerze określić, jaki jest stan ich pracy i przyznać się, kiedy po prostu czegoś nie są w stanie rozwiązać.
Chętnie pomaga i pozwala sobie pomóc.
Programowanie to sport zespołowy. Zazwyczaj pracujemy w grupie. Niezwykle cenna jest gotowość pomocy innym osobom, nawet kosztem niewielkich opóźnień we własnym zadaniu. Ten punkt dobrze łączy się również ze wspomnianą wcześniej dbałością o dobro całej aplikacji.
Z drugiej strony istotna jest również umiejętność przyjmowania pomocy. Warto, aby programista potrafił przyznać, że po spędzeniu nad zadaniem dłuższej chwili czasu, w dalszym ciągu nie wie, od czego zacząć. Ta umiejętność nie zawsze jest oczywista. Często trudno nam przezwyciężyć własne ego i nieodpartą chęć rozwiązania zadania samemu. Tymczasem jako zespół projekt na tym traci i nie wykorzystuje w pełni swojego potencjału.
Jest dokładny.
Ostatnia cecha, którą chciałabym wyróżnić, to dokładność. Czasem zaprogramowanie tak zwanego happy path nie zajmuje dużo czasu. Później natomiast diabeł tkwi w szczegółach. Od tego zależy, ile razy tester będzie zwracał zadanie do poprawy po testach manualnych. Często warto, aby deweloper sam zastanowił się, jak potencjalnie można byłoby zepsuć jego funkcjonalność. To właśnie ta cecha pozwala mieć pełne zaufanie do implementacji jednej osoby, podczas gdy pracę innej osoby chcemy sprawdzać dokładniej. Nie budzi ona naszego zaufania.
I to już wszystko. Mam nadzieję, że ten artykuł da Wam trochę inne spojrzenie na ocenianie programistów, niezależnie od tego po której stronie- ocenianego czy też oceniającego stoicie.
A Wy? Być może kierujecie się jakimiś dodatkowymi kryteriami, które są istotne w ocenie programistów? Koniecznie napiszcie o tym w komentarzach!