Programování

Zkoumání principu substituce Liskov

Termín SOLID je populární zkratka používaná k označení souboru pěti principů softwarové architektury. Mezi ně patří: SRP (Single Responsibility), Open / Close, Liskov's Substitution, Interface Segregation a Dependency Inversion.

LSP (Liskov Substitution Principle) je základní princip OOP a uvádí, že odvozené třídy by měly být schopné rozšířit své základní třídy bez změny jejich chování. Jinými slovy, odvozené třídy by měly být vyměnitelné pro své základní typy, tj. Odkaz na základní třídu by měl být vyměnitelný za odvozenou třídu bez ovlivnění chování. Princip substituce Liskov představuje silný podtyp chování a byl zaveden Barbarou Liskov v roce 1987.

Podle Barbary Liskovové „je zde požadováno něco jako následující substituční vlastnost: Pokud pro každý objekt o1 typu S existuje objekt o2 typu T takový, že pro všechny programy P definované v termínech T je chování P se nemění, když je o1 nahrazeno o2, pak S je podtyp T. "

Klasickým příkladem porušení principu substituce Liskov je problém Obdélník - čtverec. Třída Square rozšiřuje třídu Rectangle a předpokládá, že šířka a výška jsou stejné.

Zvažte následující třídu. Třída Rectangle obsahuje dva datové členy - šířku a výšku. Existují také tři vlastnosti - Výška, Šířka a Plocha. Zatímco první dvě vlastnosti nastavují výšku a šířku obdélníku, vlastnost Area má getr, který vrací plochu obdélníku.

 třída Obdélník

    {

chráněná int šířka;

chráněná výška int;

public virtual int Šířka

        {

dostat

            {

návratová šířka;

            }

soubor

            {

šířka = hodnota;

            }

        }

 

public virtual int Výška

        {

dostat

            {

návratová výška;

            }

soubor

            {

výška = hodnota;

            }

        }

               

public int Area

        {

dostat

            {

návratová výška * šířka;

            }

         }    

    }

Čtverec je typ obdélníku, jehož všechny strany mají stejnou velikost, tj. Šířka a výška čtverce jsou stejné.

třída Square: Rectangle

    {

public override int Width

        {

dostat

            {

návratová šířka;

            }

soubor

            {

šířka = hodnota;

výška = hodnota;

            }

        }

veřejné přepsání int Výška

        {

dostat

            {

návratová šířka;

            }

soubor

            {

šířka = hodnota;

výška = hodnota;

            }

        }

    }

Zvažte další třídu nazvanou ObjectFactory.

 třída ObjectFactory

    {

veřejný statický obdélník GetRectangleInstance ()

        {

vrátit nový čtverec ();

        }

    }

Všimněte si, že nastavovače vlastností Width a Height ve třídě Square byly přepsány a upraveny tak, aby byla zajištěna stejná výška a šířka. Pojďme nyní vytvořit instanci třídy Rectangle pomocí třídy a nastavit její vlastnosti výšky a šířky.

Obdélník s = ObjectFactory.GetRectangleInstance ();

s.výška = 9;

s.Šířka = 8;

Console.WriteLine (s.Area);

Výše uvedený fragment kódu při spuštění zobrazí v konzole hodnotu 64. Očekávaná hodnota je 72, protože uvedená šířka a výška je 9, respektive 8. Jedná se o porušení zásady střídání Liskov. Důvodem je, že třída Square, která rozšířila třídu Rectangle, změnila chování. Aby bylo zajištěno, že nebude porušen princip substituce Liskov, třída Square může rozšířit třídu Rectangle, ale neměla by měnit chování. Chování bylo změněno úpravou stavitelů pro vlastnosti Width a Height. Hodnoty výšky a šířky jsou stejné, pokud se jedná o čtverec - neměly by být stejné, pokud se jedná o obdélník.

Jak to napravíme, tj. Zajistíme, aby tato zásada nebyla porušena? Můžete si nechat představit novou třídu nazvanou Quadrilateral a zajistit, aby třídy Rectangle i Square rozšířily třídu Quadrilateral.

 veřejná třída Quadrilateral

    {

public virtual int Výška {get; soubor; }

public virtual int Šířka {get; soubor; }

public int Area

        {

dostat

            {

návrat Výška * Šířka;

            }

        }

    } 

Nyní by třídy Rectangle a Square měly rozšířit třídu Quadrilateral a vhodně nastavit hodnoty vlastností Width a Height. V podstatě by odvozené třídy měly mít nezbytnou funkcionalitu pro nastavení hodnot na tyto vlastnosti na základě typu instance Quadrilateral, pro kterou potřebujete vypočítat plochu. Všimněte si, že vlastnosti Výška i Šířka byly ve třídě Čtyřúhelník označeny jako virtuální, což znamená, že tyto vlastnosti by měly být přepsány třídami, které odvozují třístrannou třídu.

Princip nahrazení Liskov je rozšířením principu Otevřít a Zavřít a je porušen, pokud máte napsaný kód, který vyvolá „neimplementované výjimky“ nebo skryjete metody v odvozené třídě, které byly v základní třídě označeny jako virtuální. Pokud váš kód dodržuje princip náhrady Liskov, máte mnoho výhod. Patří mezi ně: opětovné použití kódu, snížené propojení a snadnější údržba.

$config[zx-auto] not found$config[zx-overlay] not found