Kilka pomysłów na kod, który łatwiej zrozumieć

Ostatnio dość sporo siedziałem w starym, odziedziczonym kodzie – nie tylko cudzym, ale i swoim. Sporo czasu zeszło mi na próby zrozumienia co autor miał na myśli… Na szczęście mogłem sobie pozwolić na wykonanie odpowiedniej refaktoryzacji z marszu – ok, część tego czego się domyśliłem umieściłem tylko w komentarzach ale tam gdzie się dało usprawnić kod od ręki – tam to zrobiłem.

Przy tej okazji chciałbym się podzielić kilkoma koncepcjami: zarówno starymi i dobrze znanymi jak i kilkoma, na które wpadłem – niekoniecznie ostatnio – zastanawiając się jak można pewne rzeczy sformułować lepiej… Ogólny zamysł przyświecającym tym ideom jest jeden – łatwiej zrozumieć co się dzieje w kodzie, także przy ewentualnym braku wsparcia ze strony VS (np. podczas łączenia gałęzi w repozytorium kodu…) gdy kod jest samo-dokumentujący. Że banał? Jasne. Tym niemniej zapraszam do lektury.

Magiczne liczby

Wszyscy niby wiemy, że magiczne numerki są złe. Bardzo złe… Dość oczywiste przykłady:

string libName = columnData.Substring(20, 13);
Item itm = collection.GetElementAt(indexRequested - 1);
// ...

Takie rzeczy zwykliśmy załatwiać za pomocą stałych, odpowiednich komentarzy, obiektów z konfiguracją itp.

Ale wszystkie one kręcą się wokół jednej rzeczy – co oznacza dany argument – skąd jego wartość, co ona oznacza dla aplikacji. Czyli np. w drugim przykładzie „1” oznacza (zazwyczaj) „korektę między systemem numeracji kolekcji, z którego korzysta algorytm dostarczający wartość zmiennej „indexRequested” do systemu numeracji wykorzystywanego przez samą kolekcję „collection„. W pierwszym przykładzie mamy jednak już dwa problemy jednocześnie – nie tylko co oznaczają podane argumenty ale jaką rolę pełnią odpowiednie parametry w wywołanej funkcji? (Ok, Susbstring() jest trywialnym przykładem – wszyscy ją znamy, ale chodzi mi o zasadę :P).

Czasami rozwiązując pierwszy problem, możemy jednocześnie rozwiązać i drugi. Np. w ten sposób:

string libName = columnData.Substring(libColumnDefinition.StartIndex, libColumnDefinition.Width);

Jednocześnie pozbywamy się magicznych liczb i umieszczamy je w konfiguracji (nawet jeśli nadal jest ona zakodowana na sztywno, to będąc trzymaną w jednym miejscu niesie o wiele więcej spójnej informacji) ale jednocześnie wskazujemy na znaczenie poszczególnych wartości dla Funkcji Substring().

Są jednak przypadki, gdy usunięcie magicznej liczby nie jest za bardzo możliwe. Np.

Timespan serviceTimeout = configuration.GetServiceTimeout(this.ServiceName) ?? new Timespan(0, 10, 0);

Czytaj dalej Kilka pomysłów na kod, który łatwiej zrozumieć

O obsłudze sytuacji wyjątkowych słów kilka

Podczas jednej z niedawnych rozmów rekrutacyjnych (w sumie to chyba lubię na nie chodzić – często są dość inspirujące 🙂 ) spotkałem się z ciekawym pytaniem – „Jakie są negatywne konsekwencje stosowania konstrukcji try-catch?” Oczywiście zbyt wiele klawiatur zjadłem, by w ciemno walnąć głupotą, że są wyłącznie same zalety. Pominę co wtedy dokładnie odpowiedziałem, ale moja własna odpowiedź skłoniła mnie by jeszcze trochę pod tym kątem pogrzebać…

Trochę postów, trochę artykułów, sprawdzenie treści kilku książek. Wygląda na to, że ten teren nie jest jeszcze zbyt dokładnie spenetrowany… Mam swoją tezę do udowaodnienia – że jeśli już się decydujemy na przechwytywanie wyjątków to czeka nas ogromna ilość planowania i pracy. Tym artykułem postaram się ją udowodnić oraz podać kilka wskazówek jak można by zabrać się do realizacji tego zadania, o czym może warto pomyśleć z wyprzedzeniem.

Jednak na początek trochę rozważań teoretycznych i to zaczynając od poziomu bardziej abstrakcyjnego. Autor (Patrick Cauldwell) książki „Code Leader” (Amazon.com) dość jasno formułuje zasadę prezentowania sytuacji wyjątkowych użytkownikowi:

Errors should only be handed off to the user if there is something that the user can do to correct the problem, and that needs to be clearly communicated. (…) It is vitally important to make your error messages to the user actionable. If an error message doesn’t tell the user how to correct the problem, then there is no point in showing the user an error message.

Oczywiście po takim oświadczeniu natychmiast powinna nastąpić gorąca debata wśród architektów i programistów:

  • które błędy prezentować?
  • co robić z błędami których nie prezentujemy?
  • co zrobić z samą aplikacją po prezentacji błędu? Zwłaszcza z przetwarzanymi danymi?
  • które sytuacje to faktyczne wyjątki, a które to łatwe do przewidzenia sytuacje nieprawidłowości?
  • które błędy – ostatecznie – należy uznać za krytyczne i zagrażające porządkowi publicznemu?

Czytaj dalej O obsłudze sytuacji wyjątkowych słów kilka