Dlaczego dużo IF-ów to źle?

0

Podobno łatwo rozpoznać początkującego programistę, bo stosuje dużo IF-ów w swoim kodzie. Wiem że niektórzy programiści są bardzo przeczuleni na punkcie IF w programowaniu obiektowym. Wiem że zbyt dużo IF-ów łamie jedną z zasad SOLID "otwarte-zamknięte". Ale dlaczego?

0

Na pewno łamie S skoro w metodzie jest wiele ifow to pewnie ma wiecej niz jedna odpowiedzialność, O tez jest łamane bo rozszerzenie funkcjonalności wymaga dodania kolejnego ifa a powinno np tylko dopisanie kolejnej implementacji interfejsu.

5

Nie zawsze dużo IF'ów to źle - ale więcej o tym w prezentacji, do której linkuję na końcu tego posta.

Warunki łamią zasadę "otwarte-zamknięte", ponieważ w momencie, w którym dojdzie Ci nowy przypadek, to musisz zmodyfikować istniejący kod. Zazwyczaj można tego uniknąć stosując polimorfizm.

class Employee {
    private int type;

    private int base;

    // konstruktor i takie tam

    public int getSalary() {
        if(type == 1) {
            return base * 1.5;
        }

        if(type == 2) {
            return base * 1.5 + 200;
        }

        return base;
    }
}

Jak Ci dojdzie kolejny typ pracownika, to musisz zmodyfikować klasę Employee. Zamiast tego mozna zrobić tak:

class Employee {
    private int base;

    // konstruktor i takie tam

    public abstract int getSalary();
}

class Junior extends Employee {
    private int base;

    // konstruktor i takie tam

    public int getSalary() {
         return base;
    }
}

class Regular extends Employee {
    private int base;

    // konstruktor i takie tam

    public int getSalary() {
         return base * 1.5;
    }
}

// itd

Mozliwe, ze cos z syntaxem powaliłem, bo na szybko pisałem :P. Zachęcam do obejrzenia prezentacji:

6

Do tego bardzo często w jednej klasie zdarza się, że ten sam warunek logiczny powtarzany jest wiele razy. A takie coś, to ewidentne miejsce na implementację jakiejś strategii, z których każda implementuje jeden z przepływów, zaś obiekty strategii są zwracane z jakiejś fabryki, w której jest dany if występuje tylko raz.

4

mnie tam najbardziej irytuje taki zapis
if (warunek == true)
albo
if (a * b ==4)
c = true
else
c = false;

4

Dużo ifów nie zawsze jest źle, ale zazwyczaj tak. Jak się pojawia, to powinna automatycznie zapalać się lampka, czy rzeczywiście problem jest dobrze przemyślany, i czy to później nie utrudni zmian/poprawek w kodzie. Mnie zazwyczaj zmusza do przemyślenia zarówno projektu jak i implementacji i w wielu przypadkach sie to opłaci, bo nagle okazuje się, że da się to zrobić lepiej i później z utrzymaniem bedzie mniej problemów.

2

Nie można ogólnie powiedzieć, że same ify są złe, bo równie dobrze można powiedzieć że "==" jest złe.
Wszystko zależy gdzie i jak.
Np. w poście by @Desu nie ify są złe tylko atrybut typu "type" (inne nazwy to "kind", "category").
Takie atrybuty od razu powinny zapalać czerwoną lampkę - czy nie da się przypadkiem ich pominąć.
Bo jeśli w klasie są, to znaczy że będą używane (w ten czy inny sposób).
Czyli takie "niby-typowanie" zamiast używania dziedziczenia klas czy strategii.

3

Jak dla mnie wiele ifów to zwykle syndrom:

  • albo programowania copy-paste (skopiuję se ifa, potem wkleję i zmodyfikuję, i tak w kółko). Takie coś jest koszmarne w utrzymaniu, bo wszelkie zmiany trzeba wdrażać we wszystkich miejscach, zamiast w jednym.

  • albo braku odpowiedniej abstrakcji, odpowiedniego wzorca (ludzie zamiast użyć np. adaptera, to robią wszystko na ifach, typu if (database == 'mysql') .... Takie coś jest złe, bo słabo to potem jest rozszerzać (jak już ktoś powiedział - złamanie open-closed principle). Jeśli chciałbyś dodać obsługę nowej bazy to musisz włożyć kolejnego ifa gdzieś, na dodatek często w iluś metodach na raz, a nie w jednej). Czyli to już jest błąd architektury (brak odpowiedniej abstrakcji), a nie tylko brzydki kod.

  • albo tego, że potrzeba sprawdzić jakieś warunki, bo faktycznie są wymagane, bo sama specyfika dziedziny tego wymaga. Może istnieć plik, gdzie będzie ze 100 ifów i też może mieć to sens, jeśli akurat trzeba sprawdzać ciągle jakieś warunki i użycie if (albo switch/case) to najprostsze co można zrobić w tym momencie (np. parsery mają często dużo ifów i switch/case).

3

Dodatkowo każdy if zwiększa złożoność cyklomatyczną co oznacza, że taki kod trudniej testować, bo jest zdecydowanie więcej możliwych ścieżek wykonania, ale tak jak koledzy wyżej mówią, wszystko zależy od zastosowania. Czasami ifów się nie da uniknąć ze względu na samą konstrukcję języka (patrzy z politowaniem na Go).

1 użytkowników online, w tym zalogowanych: 0, gości: 1