Skip to content

Open Closed Principle

Miért?
Azért, mert új feature-ök hozzáadásával egy addig hibátlan rendszer instabillá válásának kockázatát a lehető legalacsonyabban kell tartani.

Az Open Closed Principle (OCP) azt mondja ki, hogy egy osztálynak nyitottnak kell lennie a bővítésre, de el kell zárkóznia a változtatások elől. Ez egy további SOLID-elv. A következő kód mutatja be, hogy milyen problémákhoz vezethet ennek az elvnek a be nem tartása:
public double Ár() {
    const decimal TörzsvásárlóiKedvezmény = 0.95m;
    switch(vásárlóTípus) {
        case VásárlóTípus.Egyszeri:
            return mennyiség * darabár;
        case VásárlóTípus.TörzsVásárló:
            return mennyiség * darabÁr * TörzsvásárlóiKedvezmény;
        default:
            throw new ArgumentOutOfRangeException();
    }
}

Ebben az implementációban az problematikus, hogy az osztályt meg kell változtatni, ha az árszámítás egy további módja kerül hozzá. Ennél nagy a veszélye annak, hogy hibát vétünk, és a már létező funkcionalitások nem működnek megfelelően. Ha vannak automatizált unit tesztek és integrációs tesztek is, még akkor is fennál annak a veszélye, hogy új bug-okat hagyunk hátra, mert nem lehet elérni százszázalékos tesztlefedettséget. Tehát általánosságban egy olyan eljárást keresünk, amely az osztályt bővíthetővé teszi anélkül, hogy az osztályt magát meg kellene változtatni. Ezt például a Strategy Pattern segítségével lehet elérni:

public interface IÁrSzámító {
    double Ár(int mennyiség, double darabÁr);
}

private IÁrSzámító árSzámító;

public double Ár() {
    return árSzámító.Ár(mennyiség, darabÁr);
}

public class EgyszeriVevő : IÁrSzámító {
    public double Ár(int mennyiség, double darabÁr) {
        return mennyiség * darabár;
    }
}

public class TörzsVásárló : IÁrSzámító {
    const decimal TörzsvásárlóiKedvezmény = 0.95m;
    
    public double Ár(int mennyiség, double darabÁr) {
        return mennyiség * darabÁr * TörzsvásárlóiKedvezmény;
    }
}

Az ár konkrét kiszámítását egy interfészen keresztül más osztályokba helyeztük. Ezáltal lehetségessé válik a tetszés szerinti bővítés az interfész új implementációival. Így az osztály nyitottá vált a bővítésekkel szemben, és egyidejűleg zárttá a változtatásokkal szemben. Létező kódot pl. a Replace Conditional with Strategy refaktorálással lehet úgy átépíteni, hogy a Open Closed Principle-t betartsuk.

Published inElvek