piątek, 31 października 2014

#Off: O programowaniu


Programowanie jest sztuką

Programowanie jest dzisiaj dla mnie sztuką. Nie chodzi o samo napisanie działającego programu. Nie jest ważne, z ilu linii kodu się składa. Nie ważne, jak wyrafinowane, mega zaawansowane metody zaimplementujemy. Ważne, aby kod był później czytelny, zoptymalizowany i przede wszystkim - zrozumiały, nie tylko dla nas.
Dobry program, to taki do którego chcemy wrócić. Ale nie po to żeby coś poprawić, lecz żeby jakąś jego część wykorzystać, bo po prostu działa doskonale. A jeśli coś działa doskonale, to wypadałoby wiedzieć nie tylko "CZY", ale "JAK", prawda?

Jeden program, wiele rozwiązań

Tworząc program, zawsze istnieje wiele rozwiązań.
Weźmy pod uwagę choćby program wykonujący prostą operację - mnożenie.
Pomijając kwestie technologiczne (aplikacja okienkowa, konsolowa, WS, czy np. DLL'ka), możemy zaszyć gotową metodę przyjmującą dwa parametry lub po prostu wykonać po prostu samo mnożenie.
Jeśli upakujemy kod w metodzie, możemy po prostu zwrócić np:

return a*b

Możemy również pokusić się o metodę, która wykona operację mnożenia iteracyjnie, dodając n-krotnie wartość pierwotną a do wyniku, z obsługą mnożenia przez zero (zwracając po prostu 0).

Powinniśmy również rozważyć, jakie wartości chcemy mnożyć  - liczby całkowite, z przecinkiem, czy uwzględniać wartości ujemne itd.

A może, jak już upakujemy nasz kod w metodzie, zamiast przekazywania na sztywno dwóch argumentów, dodać tablicę, dzięki czemu w jednej metodzie wykonamy mnożenie n-liczb? A może warto przeciążyć metodę i stworzyć jej różne warianty? :)

Programowanie daje nam dowolność w realizacji pewnych rozwiązań. To od nas zależy, w jaki sposób zrealizujemy kod, oraz czy istotnie spełni on nasze oczekiwania.

Liczy się wnętrze...

Tworząc programy bardzo często kompilujemy je, jak działa wszystko ok, zapominamy o "wnętrzu". Nie zapominajmy jednak, że kiedyś być może będziemy chcieli wrócić do kodu, aby coś poprawić, udoskonalić, a być może nasz program realizował już coś czego potrzebujemy w nowym projekcie i warto wykorzystać stosowny fragment kodu lub stworzony komponent.


Dlatego podczas tworzenia kodu wyobraźmy sobie, że minęły 3 lata, zapomnieliśmy jak działa program "od środka" i odpowiedzmy sobie na pytania:
  • Czy kod jest wystarczająco czytelny? Czy za jakiś czas będę wiedział, do czego służy zmienna o nazwie xxx1?
  • Czy nie powinienem zastanowić się nad nazwami niektórych funkcji? Może warto je upakować w pewną klasę? Raczej nie wszystkie metody powinny być "public", niektóre mogą być dodatkowo do wykorzystania bez deklarowania, może warto przekształcić je na statyczne? Do czego służy metoda o nazwie Licz(int a, int b)? dzisiaj wiem, że sprawdza czy a jest podzielne przez b, kod również na to wskazuje - ale może jednak warto zmienić nazwę funkcji na bardziej rozsądną?
  • Może warto dopisać kilka stosownych komentarzy, abym wiedział, co się dzieje w danym momencie?
  • A może dobrym pomysłem będzie odseparowanie części naszego "programiku" do osobnej DLL'ki? W końcu tę metodę Foo(int bar) wykorzystuję w co trzecim programie; jeśli okaże się że był jakiś błąd, wystarczy że podmienię wtedy DLL'kę w programach, które z niej korzystają.
Nie ważne jak ładny interfejs użytkownika utworzymy, jakimi "wodotryskami" zachwyci nas czy potencjalnego odbiorcę.
Poza działającym programem (co jest oczywiście najwyższym priorytetem), najważniejsze jest to czego nie widać, czyli kod.

Przykłady z życia:
  1. Jeśli samochód się zepsuje,  mechanik wykonuje rozpoznanie - problem (samochód nie odpala) poznaje przyczynę (np. uszkodzona świeca), odnajduje rozwiązanie (wymiana świecy). Dlaczego wymiana świecy zajmie mu technicznie ujmując kilka minut? Ponieważ wie, gdzie szukać, jest zachowany pewien standard, świece nie są "klejone", wystarczy wymienić ten element, bez potrzeby rozbierania całego silnika.
Pamiętajmy też, że program jest jak kobieta:

Umawiasz się z dziewczyną na randkę, idziecie do restauracji. wszystko ładnie, pięknie, cudowne atrybuty, nasza partnerka wykazuje dużo interakcji, no i przechodzicie do konkretów... rozbierasz partnerkę żeby ją lepiej poznać, a tu.... No, niekoniecznie to czego się spodziewaliśmy :)

Mniej znaczy więcej. Więcej znaczy mniej

Głównym problemem wielu programistów jest tworzenie bardzo złożonego kodu, bez późniejszego upakowania fragmentów w możliwe do późniejszego wykorzystania metody, czy też bez jakiejkolwiek optymalizacji.
Konsekwencją tego są nigdy niezadeklarowane zmienne (o tym na szczęście poinformują już nas środowiska programistyczne), niepotrzebne fragmenty kodu, które jedynie zwiększają złożoność obliczeniową, oczywiście nieczytelność kodu.
Oczywiście nie zawsze muszą wystąpić powyższe konsekwencje. Często możemy dysponować ładnym, zwięzłym kodem. Tylko czemu taki fragment kodu upakować np bezpośrednio pod "button1_click(sender,e)"? Jeśli gdzieś pojawi się analogiczna funkcjonalność, oczywiście - możemy po drodze w kodzie "kliknąć" przycisk - ale czy to jest ładne rozwiązanie?

Czyż nie lepszym rozwiązaniem byłoby stworzenie odrębnej metody o bardziej logicznej nazwie niż nazwa akcji wybranej kontrolki?

Może jednak założyć, że funkcjonalność pojawi się nie tylko w wybranej klasie (kontrolce) i przenieść jej funkcjonalność do pewnej klasy?

Mniej znaczy więcej --> Mniej linii kodu = większy porządek i z reguły wydajność
Więcej znaczy mniej --> Więcej zachodu na początku =  mniej późniejszych modyfikacji i poprawek.

NAZWY, Names, nazwy1...

Jednym z grzechów programistów jest nazywanie "jak popadnie". Typowe błędy:
  • Brak stosowania standardu wielkości liter (np nazwy rozpoczynające od dużej litery to klasy)
  • Nic nie mówiące nazwy zmiennych, czy klas (np Class1)
  • Wielojęzyczność :) czasami opisujemy ładnie, po angielsku; w innych przypadkach pojawia się z reguły język ojczysty
  • Wiele klas o takiej samej nazwie, a różnej funkcjonalności; np klasa maintain.User i application.User, do tego Forms.User. Pomimo stosowania namespace'ów, myślę że warto zastosować inne nazwy klas - w końcu pełnią one zupełnie inną funkcję.

Poza bardzo kreatywnym podejściem do nazywania różnych elementów, np "zapożyczając" fragment kodu np. z "gotowców", zapominamy o detalu pt "źródło" czy krótka informacja o licencji (choćby GPL).
Oczywiście w kontekście działania naszego programu nie ma to większego znaczenia. Niemniej jednak, czy tworząc kod, który udostępniamy w sieci, chcielibyśmy aby ktoś przypisywał sobie wszelkie zasługi za działający program? Niezależnie od podejścia do własności intelektualnej - nie sądzę.


Podsumowanie

Podczas tworzenia programów dobrze jest pamiętać o wielu "dobrych zasadach". Oczywiście samo programowanie jest procesem, w którym my jako programiści mamy wiele do powiedzenia, wdrożenia, usprawnienia. Twórzmy oprogramowanie, z którego istotnie będziemy dumni. Zastanówmy się nad optymalnym rozwiązaniem. Już podczas tworzenia wersji 1.0 myślmy o tym, że kiedyś powstanie wersja 4.0 i kolejne, więc warto od razu uczytelnić i zoptymalizować nasz kod... nawet jeśli do takich zmian nie dojdzie.

X3