본문 바로가기
Python Object-oriented Programming

Liskov Substitution Principle

by 자동매매 2023. 4. 4.

출처 :https://www.pythontutorial.net/python-oop/python-liskov-substitution-principle/

 

Python Liskov Substitution Principle

In this tutorial, you'll learn about the Liskov Substitution Principle and how to implement it in Python.

www.pythontutorial.net

 

 

Introduction to the Liskov substitution principle

 

SOLID는 Uncle Bob에 의한 5 가지 소프트웨어 디자인 원칙 나타내는 약어입니다.

  •  – Single responsibility Principle
  •   Open-closed Principle
  • L  – Liskov Substitution Principle
  •   Interface Segregation Principle
  •   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

댓글