Skip to content

Ogólne cz. 1/2 – ZK #4

Działania implementujmy w sposób oczywisty

Jako programiści powinniśmy dążyć do tego, aby każde implementowane przez nas działanie było zapisane w sposób oczywisty. Jest to istotne, ponieważ jeżeli w przyszłości nasz kod będzie wykorzystywany przez innego programistę to wątpię aby był zadowolony z kodu, który wprowadza go w błąd lub dezorientację. Traktuje o tym tzw. Principle of Least Astonishment. W internecie możemy znaleźć następujące jej wyjaśnienie (źródło):

The Principle of Least Astonishment states that the result of performing some operation should be obvious, consistent, and predictable, based upon the name of the operation and other clues.

Innymi słowy musimy pamiętać głównie o zachowaniu poprawnego nazewnictwa oddającego realny stan rzeczy. Przykładowo:

class MyStack {
    // some code
    
    // should be named peek() !
    int pop() {
        return stack[0];
    }
    
    // more code
}

 Zdejmowanie zabezpieczeń

Jak trafnie zauważa w swojej książce Robert Martin, do wybuchu w Czarnobylu doszło ponieważ dyrektor elektrowni zdecydował się wyłączyć coraz to większą liczbę zabezpieczeń. Dlaczego? Rzekomo utrudniały mu przeprowadzanie eksperymentu, który koniec końców i tak się nie udał. Resztę historii raczej dobrze znamy.

Źródło: fotokomorka.com

Pomimo, że przykład może wydawać się skrajny – wcale taki nie jest! W końcu ogromna rzesza programistów pracuje np. w bankach, urzędach, wojsku lub elektrowniach. Jeżeli programiście zaniedbają tam swoje obowiązki, a nikt należycie tego nie skontroluje to mogą wyrządzić ogromne szkody firmie, a nawet społeczeństwu. Autor książki ciekawie opisuje ten aspekt na swoim blogu pod tym adresem.

We programmers. We rule the world. We write the rules that make our society work.

Bądźmy więc odpowiedzialni i dbajmy o zabezpieczenia z należytym dla nich szacunkiem!

Powtórzenia

Sądzę, że o zasadzie DRY (Don’t Repeat Yourself) powinien słyszeć każdy. Wpisując nazwę tej zasady na wikipedii, możemy znaleźć następującą definicję:

In software engineering, don’t repeat yourself (DRY) is a principle of software development, aimed at reducing repetition of information of all kinds, especially useful in multi-tier architectures. The DRY principle is stated as „Every piece of knowledge must have a single, unambiguous, authoritative representation within a system”.

Wbrew pozorom jej sens jest głębszy niż mogłoby się wydawać na pierwszy rzut oka. Dave Thomas, Andy Hunt, Kent Beck (nazwał ją również jako Once and only once) czy Robert Martin uznają ją za jedną z fundamentalnych zasad programowania. Każde napotkane powtórzenie najczęściej stanowi nic innego jak utraconą możliwość przeniesienia logiki na wyższy poziom abstrakcji. Powtórzony kod najczęściej można wyodrębnić do osobnych metod, a metody o podobnym zakresie funkcjonalności prawdopodobnie powinny zostać wydzielone do osobnych klas. Klasy, które wyglądają podobnie również powinny zostać przeniesione na wyższy poziom abstrakcji dzięki zastosowaniu interfejsów lub klas abstrakcyjnych. Z pomocą przychodzi nam tutaj m.in. wiele wzorców projektowych (o dwóch nieco spokrewnionych pisałem swojego czasu na blogu: Metoda szablonowa oraz Budowniczy). Temat jest na tyle szeroki oraz istotny, że prawdopodobnie stworzę osobny, stosowny wpis w przyszłości. Tym czasem zachęcam do zrobienia małego research’u na ten temat!

Nadklasy zależne od swoich podklas

Z reguły ważnym jest, aby nadklasy nie wiedziały nic o swoich podklasach. Zdarzają się co prawda różne odstępstwa od tej zasady (patrz niektóre wzorce projektowe oraz specyficzne sytuacje), aczkolwiek zazwyczaj powinniśmy mieć możliwość udostępniania nadklas oraz podklas w osobnych plikach jar.  Przecież zawsze dążymy do tego, aby poszczególne moduły kodu były od siebie jak najbardziej niezależne! Dzięki pamiętaniu o zachowaniu odpowiedniego kierunku przepływu zależności w strukturze obiektowej możemy zachować stosowną elastyczność naszego kodu.

Separacja pionowa

Funkcje oraz zmienne powinny być definiowane jak najbliżej miejsca, w którym są wykorzystywane pierwszy raz. Zmienne lokalne powinny być deklarowane tuż nad miejscem pierwszego użycia. Najłatwiej pokazać to na prostym przykładzie:

class User {
    // some code
    // ..
    // ..
    
    private String generateUid() {
        StringBuilder builder = new StringBuilder();
        
        builder.append(departName);
        builder.append("_")
        builder.append(managerRid);
        builder.append("_");
        builder.append(calculateUid());
        
        return builder.toString();
    }
    
    private String calculateUid() {
        int rid = calculateUserRid();
        // some logic to calculate uid based on rid
        
        return uid;
    }
    
    private int calculateUserRid() {
        // some logic to calculate rid
        return userRid;
    }
    
    // more code
}

Kategoria Ogólne została rozbita na dwa mniejsze fragmenty ze względu na swoją dużą objętość. Adres do części drugiej zostanie podany w tym miejscu.

Informacje na temat cyklu i źródeł:

Facebooktwitterredditlinkedinmail
Published inProgramowanie