Programmering

Udforskning af Liskov-substitutionsprincippet

Udtrykket SOLID er et populært akronym, der bruges til at henvise til et sæt af fem principper for softwarearkitektur. Disse inkluderer: SRP (Single Responsibility), Open / Close, Liskov's Substitution, Interface Segregation og Dependency Inversion.

LSP (Liskov Substitution Principle) er et grundlæggende princip i OOP og siger, at afledte klasser skal være i stand til at udvide deres basisklasser uden at ændre deres adfærd. Med andre ord bør afledte klasser være udskiftelige for deres basetyper, dvs. en henvisning til en basisklasse skal kunne udskiftes med en afledt klasse uden at påvirke adfærden. Liskov-substitutionsprincippet repræsenterer en stærk adfærdsmæssig undertypning og blev introduceret af Barbara Liskov i året 1987.

Ifølge Barbara Liskov er "Det, der ønskes her, noget i retning af følgende substitutionsegenskaber: Hvis der for hvert objekt o1 af type S er et objekt o2 af typen T, således at P for alle programmer P defineret i form af T, er uændret, når o1 er substitueret med o2, så er S en undertype af T. "

Et klassisk eksempel på overtrædelse af Liskov-substitutionsprincippet er problemet med rektangel - firkant. Firkantklassen udvider klassen Rektangel og antager, at bredden og højden er ens.

Overvej følgende klasse. Rektangelklassen indeholder to dataelementer - bredde og højde. Der er også tre egenskaber - højde, bredde og areal. Mens de to første egenskaber indstiller højden og bredden af ​​rektanglet, har egenskaben Area en getter, der returnerer arealet af rektanglet.

 klasse rektangel

    {

beskyttet int bredde;

beskyttet int højde;

offentlig virtuel int Bredde

        {

            {

returbredde

            }

sæt

            {

bredde = værdi;

            }

        }

 

offentlig virtuel int Højde

        {

            {

returhøjde

            }

sæt

            {

højde = værdi;

            }

        }

               

offentlige int-område

        {

            {

returhøjde * bredde;

            }

         }    

    }

En firkant er en type rektangel, hvis sider er af samme størrelse, dvs. bredden og højden af ​​en firkant er den samme.

klasse Firkant: Rektangel

    {

offentlig tilsidesættelse af bredde

        {

            {

returbredde

            }

sæt

            {

bredde = værdi;

højde = værdi;

            }

        }

offentlig tilsidesættelse af højde

        {

            {

returbredde

            }

sæt

            {

bredde = værdi;

højde = værdi;

            }

        }

    }

Overvej en anden klasse kaldet ObjectFactory.

 klasse ObjectFactory

    {

offentlig statisk rektangel GetRectangleInstance ()

        {

returner ny firkant ();

        }

    }

Bemærk, at sætterne for egenskaberne Bredde og Højde i kvadratklassen er blevet tilsidesat og ændret for at sikre, at højden og bredden er den samme. Lad os nu oprette en forekomst af klassen Rektangel ved hjælp af og indstille egenskaberne for højde og bredde.

Rektangel s = ObjectFactory.GetRectangleInstance ();

s.Højde = 9;

s.Bredde = 8;

Console.WriteLine (s.Area);

Ovenstående kodestykke, når det blev udført, ville vise værdien 64 i konsollen. Den forventede værdi er 72, da den nævnte bredde og højde er henholdsvis 9 og 8. Dette er en krænkelse af Liskov-substitutionsprincippet. Dette skyldes, at den firkantede klasse, der har udvidet klassen Rektangel, har ændret adfærd. For at sikre, at Liskov-substitutionsprincippet ikke overtrædes, kan Square-klassen udvide Rectangle-klassen, men bør ikke ændre adfærden. Adfærden er blevet ændret ved at ændre setterne for både egenskaberne Bredde og Højde. Værdierne for højde og bredde er ens, hvis det er en firkant - de skal ikke være de samme, hvis det er et rektangel.

Hvordan løser vi dette, dvs. sikrer, at dette princip ikke krænkes? Nå, du kan få en ny klasse introduceret kaldet Quadrilateral og sikre, at både Rektangel og Square klasser udvider Quadrilateral klassen.

 offentlig klasse firkantet

    {

offentlig virtuel int Højde {get; sæt; }

offentlig virtuel int Bredde {get; sæt; }

offentlige int-område

        {

            {

retur Højde * Bredde;

            }

        }

    } 

Nu skal både rektangel- og firkantklasserne udvide den firkantede klasse og indstille værdierne for egenskaberne Bredde og Højde passende. I det væsentlige skal de afledte klasser have den nødvendige funktionalitet til at indstille værdier til disse egenskaber baseret på typen af ​​den firkantede forekomst, du skal beregne areal for. Bemærk, at både egenskaberne Højde og Bredde er blevet markeret som virtuelle i klassen Quadrilateral, hvilket betyder, at disse egenskaber skal tilsidesættes af de klasser, der udleder Quadrilateral-klassen.

Liskov-substitutionsprincip er en udvidelse af Open Close-princippet og overtrædes, når du har skrevet kode, der kaster "ikke implementerede undtagelser", eller du skjuler metoder i en afledt klasse, der er markeret som virtuel i basisklassen. Hvis din kode overholder Liskov-substitutionsprincippet, har du mange fordele. Disse inkluderer: genanvendelighed af kode, reduceret kobling og lettere vedligeholdelse.

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