SÓLIDO — De Zero a Batata 3

Mar 31 2023
Sobre o Princípio de Substituição de Liskov (LSP) Hoje continuarei a explicar sobre o Princípio de Substituição de Liskov (LSP) neste artigo, você pode ler meu artigo anterior sobre o princípio da responsabilidade única e o princípio aberto/fechado (OCP) lá. Antes de passar para a explicação detalhada sobre o LSP, devemos saber como o LSP é útil em nosso trabalho diário.

Sobre o Princípio de Substituição de Liskov (LSP)

Hoje continuarei explicando sobre o Princípio de Substituição de Liskov (LSP) neste artigo, você pode ler meu artigo anterior sobre o princípio da responsabilidade única e o princípio aberto/fechado (OCP) lá .

Antes de passar para a explicação detalhada sobre o LSP , devemos saber como o LSP é útil em nosso trabalho diário. O LSP nos ajuda a modelar boas hierarquias de herança. Isso nos ajuda a evitar hierarquias de modelo que não estejam em conformidade com o princípio Aberto/Fechado. Qualquer modelo de herança que aderir ao Princípio de Substituição de Liskov seguirá implicitamente o princípio Aberto/Fechado .

Vamos pular para a codificação, a propósito, se você não entende sobre kotlin, não se preocupe, o LSP pode implementar em qualquer idioma para que você possa tentar com o seu favorito.

Temos uma Studentturma que possui um calculateGPAmétodo que calcula o GPA com base nas notas do aluno:

open class Student(val grades: List<Double>) {
    open fun calculateGPA(): Double {
        // calculate the GPA based on the grades
    }
}

class HonorsStudent(grades: List<Double>) : Student(grades) {
    override fun calculateGPA(): Double {
        // calculate the GPA based on a different set of rules for honors students
    }
}

Para aderir ao LSP, podemos modificar o design das classes. Uma maneira de fazer isso é criar uma nova interface chamada GPAque tenha um calculatemétodo:

interface GPA {
    fun calculate(): Double
}

open class Student(val grades: List<Double>) : GPA {
    override fun calculate(): Double {
        // calculate the GPA based on the grades
    }
}

class HonorsStudent(grades: List<Double>) : GPA {
    override fun calculate(): Double {
        // calculate the GPA based on a different set of rules for honors students
    }
}

Isso está de acordo com o Princípio de Substituição de Liskov porque qualquer código que espera um objeto do tipo GPApode ser passado como um Studentobjeto ou um HonorsStudentobjeto, e o comportamento do calculatemétodo será consistente em ambos os objetos.

Ao separar o calculateGPAcomportamento em uma interface separada, garantimos que qualquer subclasse que implemente essa interface se comporte de maneira consistente com outros objetos desse tipo de interface.

Obrigado por tomar o tempo para ler este artigo. Espero que minha escrita tenha sido informativa e instigante.