출처 :https://www.pythontutorial.net/python-oop/python-liskov-substitution-principle/
Introduction to the Liskov substitution principle
SOLID는 Uncle Bob에 의한 5 가지 소프트웨어 디자인 원칙을 나타내는 약어입니다.
- S – Single responsibility Principle
- O – Open-closed Principle
- L – Liskov Substitution Principle
- I – Interface Segregation Principle
- D – Dependency Inversion Principle
Liskov substitution principle (LSV)는 자식 클래스가 부모 클래스를 대체 할 수 있어야한다고 말합니다. Liskov 대체 원칙은 자식 클래스가 오류를 일으키지 않고 부모 클래스의 자리를 차지할 수 있도록 하는 것을 목표로 합니다 .
다음 예제를 고려하십시오.
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', 'john@test.com')
이 예제에는 Notification, Email 및 SMS의 세 가지 클래스가 있습니다. Email 및 SMS 클래스는 Notification 클래스에서 상속됩니다.
Notification 추상 클래스에는 email 주소로 메시지를 보내는 notify() 메서드가 있습니다.
Email 클래스의 notify() 메서드는 email로 메시지를 보냅니다.
그러나 SMS 클래스는 메시지를 보내기 위해 email이 아닌 전화 번호를 사용합니다. 따라서 email 대신 전화 번호를 수락하도록 SMS 클래스의 notify() 메서드의 서명을 변경해야합니다.
다음 NotificationManager 클래스는 메시지를 Contact로 보내기 위해 Notification를 이용한다.
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', 'john@test.com', '(408)-888-9999')
notification_manager = NotificationManager(SMS(), contact)
notification_manager.send('Hello John')
클래스의 send() 메서드는 message 개체를 받아들입니다. message이 Email 또는 SMS의 인스턴스인지 확인하고 연락처의 email과 전화를 각각 notify() 메서드에 전달합니다.
Conform with the Liskov substitution principle
먼저 email 매개 변수를 포함하지 않도록 Notification 클래스의 notify() 메서드를 다시 정의합니다.
class Notification(ABC):
@abstractmethod
def notify(self, message):
pass
둘째, Email 클래스의 __init__ 메서드에 email 매개 변수를 추가합니다.
class Email(Notification):
def __init__(self, email):
self.email = email
def notify(self, message):
print(f'Send "{message}" to {self.email}')
셋째, SMS 클래스의 __init__ 메서드에 phone 매개 변수를 추가합니다.
class SMS(Notification):
def __init__(self, phone):
self.phone = phone
def notify(self, message):
print(f'Send "{message}" to {self.phone}')
넷째, NotificationManager클래스를 변경합니다.
class NotificationManager:
def __init__(self, notification):
self.notification = notification
def send(self, message):
self.notification.notify(message)
전체 Code
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', 'john@test.com', '(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')
Summary
- Liskov substitution principle(Liskov 대체 원칙)은 자식 클래스가 부모 클래스를 대체 할 수 있어야한다고 말합니다 .
'Python Object-oriented Programming' 카테고리의 다른 글
Multiple inheritance (0) | 2023.04.04 |
---|---|
Interface Segregation Principle (0) | 2023.04.04 |
Open-closed Principle (0) | 2023.04.04 |
Single Responsibility Principle (0) | 2023.04.04 |
enum-auto (0) | 2023.04.04 |
댓글