O concepto deste principio foi introducido por Barbara Liskov nunha conferencia maxistral de 1987 e posteriormente publicado nun artigo xunto con Jannette Wing en 1994. defición orixinal é a seguinte:
Sexa q (x) unha propiedade demostrable en obxectos x de tipo T. Entón q (y) debería ser demostrable para obxectos y de tipo S onde S é un subtipo de T.
Posteriormente, coa publicación dos principios SOLID de Robert C. Martin no seu libro Agile Software Development, Principles, Patterns, and Practices e despois republicados na versión C# do libro Agile Principles, Patterns, and Practices en C#, o deficoñecíase como principio de substitución de Liskov.
Isto lévanos ao defiinformación dada por Robert C. Martin: Os subtipos deben ser substituíbles polos seus tipos de base.
clase Vehículo {
función startEngine () {
// Funcionalidade de arranque predeterminada do motor
}
función accelerate () {
// Funcionalidade de aceleración predeterminada
}
}
Dada unha clase de vehículo (pode ser abstracta) e dúas implementacións:
clase Car estende Vehículo {
función startEngine () {
$ this-> engageIgnition ();
pai :: inicioEngine ();
}
función privada engageIgnition () {
// Procedemento de ignición
}
}
clase ElectricBus amplía o vehículo {
función accelerate () {
$ this-> increaseVoltage ();
$ this-> connectIndividualEngines ();
}
función privada incrementarVoltaxe () {
// Lóxica eléctrica
}
función privada connectIndividualEngines () {
// Lóxica de conexión
}
}
condutor de clase {
function go (Vehículo $ v) {
$ v-> startEngine ();
$ v-> accelerate ();
}
}
O que nos leva a unha implementación sinxela do Patrón de Deseño de Métodos de Modelo tal e como o empregamos no OCP.
Tamén che pode interesar o segundo principio SOLID: https: //bloginnovazione.gl / principio-segundo-solido-aberto-pechado / 3906 /
Baseado na nosa experiencia previa co principio Aberto / Pechado, podemos concluír que o principio de substitución de Liskov está intimamente relacionado co OCP. De feito, "unha violación de LSP é unha violación latente de OCP" (Robert C. Martin), e o Patrón de deseño de métodos de modelo é un exemplo clásico de respecto e implementación de LSP, que á súa vez é unha das solucións para cumprir tamén con OCP.
clase Rectángulo {
privado $ topEsquerda;
$ ancho privado;
$ altura privada;
función pública setHeight ($ height) {
$ this-> height = $ height;
}
función pública getHeight () {
devolver $ esta-> altura;
}
función pública setWidth ($ width) {
$ this-> width = $ width;
}
función pública getWidth () {
devolve $ este-> ancho;
}
}
Comecemos cunha forma xeométrica básica, un rectángulo. É só un sinxelo obxecto de datos con axustes e obtencións de ancho e alto. Imaxina que a nosa aplicación funciona e xa está implantada en varios clientes. Agora necesitan unha nova función. Deben ser capaces de manipular cadrados.
Na vida real, en xeometría, un cadrado é unha forma particular dun rectángulo. Polo tanto, poderiamos intentar implementar unha clase Square que estenda unha clase Rectangle. A miúdo dise que unha clase infantil é unha clase principal e esta expresión tamén se axusta a LSP, polo menos a primeira vista.
clase cadrado estende Rectángulo {
función pública setHeight (valor $) {
$ this-> width = $ value;
$ this-> height = $ value;
}
función pública setWidth ($ value) {
$ this-> width = $ value;
$ this-> height = $ value;
}
}
Un cadrado é un rectángulo con ancho e altura iguais e poderiamos facer unha implementación estraña como no exemplo anterior. Poderiamos anular os dous axustadores para establecer a altura e a anchura. Pero, como afectará isto ao código do cliente?
Cliente de clase {
función areaVerifier (Rectángulo $ r) {
$ r-> setWidth (5);
$ r-> setHeight (4);
if ($ r-> area ()! = 20) {
lanza unha nova excepción ("¡Área mala!");
}
volver certo;
}
}
área de función () {
devolver $ this-> width * $ this-> height;
}
Obviamente engadimos o método anterior á nosa clase de Rectángulo para proporcionar a área.
clase LspTest estende PHPUnit_Framework_TestCase {
función testRectangleArea () {
$ r = novo rectángulo ();
$ c = novo cliente ();
$ this-> assertTrue ($ c-> areaVerifier ($ r));
}
}
E creamos unha proba sinxela enviando un obxecto rectángulo en branco ao verificador de área e a proba pasa. Se a nosa praza de clase é deficorrectamente, envialo ao areaVerifier() do Cliente non debería romper a súa funcionalidade. Despois de todo, un cadrado é un rectángulo en todos os sentidos matemáticos. Pero é a nosa clase?
función testSquareArea () {
$ r = novo cadrado ();
$ c = novo cliente ();
$ this-> assertTrue ($ c-> areaVerifier ($ r));
}
Entón, a nosa clase Square non é un Rectángulo despois de todo. Incumpre as leis da xeometría. Falla e viola o principio de substitución de Liskov.
Ercole Palmeri
O desenvolvemento da motricidade fina a través da cor prepara aos nenos para habilidades máis complexas como escribir. Para colorear…
O sector naval é unha verdadeira potencia económica mundial, que navega cara a un mercado de 150 millóns...
O pasado luns, o Financial Times anunciou un acordo con OpenAI. FT licencia o seu xornalismo de clase mundial...
Millóns de persoas pagan por servizos de streaming, pagando taxas de subscrición mensuais. É unha opinión común que vostede...