Princípio de substituição de Python Liskov

Resumo : neste tutorial, você aprenderá sobre o Princípio de Substituição de Liskov e como implementá-lo em Python.

Introdução ao princípio de substituição de Liskov

O princípio de substituição de Liskov (LSV) é um dos cinco princípios dos princípios SOLID. O L em SOLID representa o princípio de substituição de Liskov.

O princípio de substituição de Liskov afirma que uma classe filha deve ser substituível por sua classe pai. O princípio de substituição de Liskov visa garantir que a classe filha possa assumir o lugar de sua classe pai sem causar erros.

Considere o seguinte exemplo:

from abc import ABC, abstractmethod


class Notification(ABC):
    @abstractmethod
    def notify(self, message, email):
        pass


class Email(Notification):
    def notify(self, message, email):
        print(f'Send {message} to {email}')


class SMS(Notification):
    def notify(self, message, phone):
        print(f'Send {message} to {phone}')


if __name__ == '__main__':
    notification = SMS()
    notification.notify('Hello', '[email protected]')Linguagem de código:  Python  ( python )

Neste exemplo, temos três classes: Notification, Email, e SMS. As classes Emaile SMSherdam da Notificationclasse.

A Notification classe abstrata possui notify()um método que envia uma mensagem para um endereço de e-mail.

O notify()método da Emailclasse envia uma mensagem para um email, o que é bom.

Porém, a SMSturma utiliza um número de telefone, e não um e-mail, para enviar uma mensagem. Portanto, precisamos alterar a assinatura do notify()método da SMSclasse para aceitar um número de telefone em vez de um email.

A NotificationManagerclasse a seguir usa o Notificationobjeto para enviar uma mensagem para a Contact:

class Contact:
    def __init__(self, name, email, phone):
        self.name = name
        self.email = email
        self.phone = phone


class NotificationManager:
    def __init__(self, notification, contact):
        self.contact = contact
        self.notification = notification

    def send(self, message):
        if isinstance(self.notification, Email):
            self.notification.notify(message, contact.email)
        elif isinstance(self.notification, SMS):
            self.notification.notify(message, contact.phone)
        else:
            raise Exception('The notification is not supported')


if __name__ == '__main__':
    contact = Contact('John Doe', '[email protected]', '(408)-888-9999')
    notification_manager = NotificationManager(SMS(), contact)
    notification_manager.send('Hello John')
Linguagem de código:  Python  ( python )

O send()método da NoticationManagerclasse aceita um objeto de notificação. Ele verifica se a notificação é uma instância do Emailou SMSe passa o email e telefone de contato para o notify()método respectivamente.

Em conformidade com o princípio de substituição de Liskov

Primeiro, redefina o notify()método da Notificationclasse para que não inclua o emailparâmetro:

class Notification(ABC):
    @abstractmethod
    def notify(self, message):
        passLinguagem de código:  Python  ( python )

Segundo, adicione o emailparâmetro ao __init__método da Emailclasse:

class Email(Notification):
    def __init__(self, email):
        self.email = email

    def notify(self, message):
        print(f'Send "{message}" to {self.email}')Linguagem de código:  Python  ( python )

Terceiro, adicione o phoneparâmetro ao __init__método da SMSclasse:

class SMS(Notification):
    def __init__(self, phone):
        self.phone = phone

    def notify(self, message):
        print(f'Send "{message}" to {self.phone}')Linguagem de código:  Python  ( python )

Quarto, mude a NotificationManagerclasse:

class NotificationManager:
    def __init__(self, notification):
        self.notification = notification

    def send(self, message):
        self.notification.notify(message)Linguagem de código:  Python  ( python )

Junte tudo:

from abc import ABC, abstractmethod


class Notification(ABC):
    @abstractmethod
    def notify(self, message):
        pass


class Email(Notification):
    def __init__(self, email):
        self.email = email

    def notify(self, message):
        print(f'Send "{message}" to {self.email}')


class SMS(Notification):
    def __init__(self, phone):
        self.phone = phone

    def notify(self, message):
        print(f'Send "{message}" to {self.phone}')


class Contact:
    def __init__(self, name, email, phone):
        self.name = name
        self.email = email
        self.phone = phone


class NotificationManager:
    def __init__(self, notification):
        self.notification = notification

    def send(self, message):
        self.notification.notify(message)


if __name__ == '__main__':
    contact = Contact('John Doe', '[email protected]', '(408)-888-9999')

    sms_notification = SMS(contact.phone)
    email_notification = Email(contact.email)

    notification_manager = NotificationManager(sms_notification)
    notification_manager.send('Hello John')

    notification_manager.notification = email_notification
    notification_manager.send('Hi John')
Linguagem de código:  Python  ( python )

Resumo

  • O princípio de substituição de Liskov afirma que uma classe filha deve ser substituível por sua classe pai.

Deixe um comentário

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