Princípio de Substituição C# Liskov

Resumo : neste tutorial, você aprenderá sobre o princípio de substituição de Liskov em C# e como aplicá-lo para construir aplicativos de software mais escaláveis ​​e de fácil manutenção.

Introdução ao Princípio de Substituição C# Liskov

O princípio de substituição de Liskove (LSP) é o terceiro princípio dos princípios SOLID de design orientado a objetos:

Observe que o princípio da substituição de Liskov recebeu o nome de Barbara Liskov , que o formulou pela primeira vez em 1988.

O princípio de substituição de Liskov afirma que se um método usa uma classe base , então ele deve ser capaz de usar qualquer uma de suas classes derivadas sem a necessidade de ter informações sobre a classe derivada.

Em outras palavras, as classes derivadas devem ser substituíveis por sua classe base sem causar erros ou efeitos colaterais. Isto significa que o comportamento da classe derivada não deve contradizer o comportamento da classe base.

Vamos dar um exemplo para entender o princípio de substituição de Liskov em C#:

namespace LSP;

public abstract class Vehicle
{
    public abstract void Drive();
}

public class Car : Vehicle
{
    public override void Drive() => Console.WriteLine("Drive a car");
}

public class Truck : Vehicle
{
    public override void Drive() => Console.WriteLine("Drive a truck");
}

public class Program
{
    public static void TestDrive(Vehicle vehicle)
    {
        vehicle.Drive();
    }
    public static void Main(string[] args)
    {
        var car = new Car();
        TestDrive(car);

        var truck = new Truck();
        TestDrive(truck);
    }
}Linguagem de código:  C#  ( cs )

Como funciona.

Primeiro, defina uma classe abstrata Vehicle que possua um Drive()método abstrato:

public abstract class Vehicle
{
    public abstract void Drive();
}Linguagem de código:  C#  ( cs )

Segundo, defina as classes Care Truckque herdam da Vehicleclasse. O Drive()método em cada classe exibe uma mensagem no console:

public class Car : Vehicle
{
    public override void Drive() => Console.WriteLine("Drive a car");
}

public class Truck : Vehicle
{
    public override void Drive() => Console.WriteLine("Drive a truck");
}Linguagem de código:  C#  ( cs )

Terceiro, defina o TestDrive()método estático na Programclasse que usa a Vehiclecomo parâmetro. O TestDrive()método estático chama o Drive()método do objeto veículo:

public class Program
{
    public static void TestDrive(Vehicle vehicle)
    {
        vehicle.Drive();
    }
    
   // ...
}Linguagem de código:  C#  ( cs )

Finalmente, passe uma instância de uma Carclasse para o TestDrive()método estático, que chama o Drive()método do Carobjeto. Da mesma forma, passe uma instância da Truckclasse para o TestDrive()método estático, que chama o Drive()método do truckobjeto:

public class Program
{
    // ...

    public static void Main(string[] args)
    {
        var car = new Car();
        TestDrive(car);

        var truck = new Truck();
        TestDrive(truck);
        
    }
}Linguagem de código:  C#  ( cs )

Este é um exemplo do princípio da substituição de Liskov em ação. Podemos usar os objetos Care Truckno TestDrive()método sem causar erros.

Em outras palavras, podemos substituir as classes derivadas ( Car& Truck) por sua classe base ( Vehicle) no TestDrive()método.

Agora, vamos violar o princípio de substituição de Liskov introduzindo uma nova classe derivada chamada Aircraft. Como você só pode pilotar uma aeronave, e não dirigi-la, o Drive()método da Aircraftclasse gera uma exceção NotImplementedException:

public class Aircraft : Vehicle
{
    public override void Drive() => throw new NotImplementedException();
}Linguagem de código:  C#  ( cs )

Quando passamos uma instância do Aircraftobjeto para o TestDrive()método, isso cria um efeito colateral (ou uma exceção)

Como não podemos substituir the Aircraftpor sua classe base Vehicleno TestDrive()método, ele viola o princípio de substituição de Liskov.

O seguinte mostra todo o programa que viola o princípio de substituição de Liskov:

namespace LSP;

public abstract class Vehicle
{
    public abstract void Drive();
}

public class Car : Vehicle
{
    public override void Drive() => Console.WriteLine("Drive a car");
}

public class Truck : Vehicle
{
    public override void Drive() => Console.WriteLine("Drive a truck");
}

public class Aircraft : Vehicle
{
    public override void Drive() => throw new NotImplementedException();
}

public class Program
{
    public static void TestDrive(Vehicle vehicle)
    {
        vehicle.Drive();
    }
    public static void Main(string[] args)
    {
        var car = new Car();
        TestDrive(car);

        var truck = new Truck();
        TestDrive(truck);

        
        var aircraft = new Aircraft();
        TestDrive(aircraft); // side effect
    }
}Linguagem de código:  C#  ( cs )

Resumo

  • O princípio de substituição de Liskov afirma que as classes derivadas devem ser substituíveis por sua classe base sem causar erros.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *