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.
- S – Princípio da Responsabilidade Única
- O – Princípio Aberto-Fechado
- L – Princípio da Substituição de Liskov
- I – Princípio de Segregação de Interface
- D – Princípio de Inversão de Dependência
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 Email
e SMS
herdam da Notification
classe.
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 Email
classe envia uma mensagem para um email, o que é bom.
Porém, a SMS
turma 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 SMS
classe para aceitar um número de telefone em vez de um email.
A NotificationManager
classe a seguir usa o Notification
objeto 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 NoticationManager
classe aceita um objeto de notificação. Ele verifica se a notificação é uma instância do Email
ou SMS
e 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 Notification
classe para que não inclua o email
parâmetro:
class Notification(ABC):
@abstractmethod
def notify(self, message):
pass
Linguagem de código: Python ( python )
Segundo, adicione o email
parâmetro ao __init__
método da Email
classe:
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 phone
parâmetro ao __init__
método da SMS
classe:
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 NotificationManager
classe:
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.