출처 : https://www.pythontutorial.net/python-oop/python-dependency-inversion-principle/
Introduction to the dependency inversion 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
Dependency Inversion Principle(종속성 반전 principle)는 다음과 같이 말합니다.
- 상위 수준 모듈은 하위 수준 모듈에 의존해서는 안 됩니다. 둘 다 추상화에 의존해야합니다.
- 추상화는 세부 사항에 의존해서는 안됩니다. 세부 사항은 추상화에 따라 달라집니다.
종속성 반전 원칙은 클래스 사이에 추상화 계층을 만들어 클래스 간의 결합을 줄이는 것을 목표로합니다.
다음 예를 참조하십시오.
class FXConverter:
def convert(self, from_currency, to_currency, amount):
print(f'{amount} {from_currency} = {amount * 1.2} {to_currency}')
return amount * 1.2
class App:
def start(self):
converter = FXConverter()
converter.convert('EUR', 'USD', 100)
if __name__ == '__main__':
app = App()
app.start()
이 예제에는 FXConverter 및 App의 두 클래스가 있습니다.
FXConverter 클래스는 API(imaginary FX third-party)를 사용하여 금액을 한 통화(currency)에서 다른 통화로 변환합니다. 간단히 하기 위해 환율을 1.2로 하드코딩했습니다. 실제로는환율을 얻기 위해 API 호출을 수행해야 합니다.
App 클래스에는 FXconverter 클래스의 인스턴스를 사용하여 100 EUR를 USD로 변환하는 start() 메서드가 있습니다.
App은 고급 모듈입니다. 그러나 App은 API에 필수적인 FXConverter 클래스에 크게 의존합니다.
앞으로 FX의 API가 변경되면 코드가 손상됩니다. 또한 다른 API를 사용하려면 App 클래스를 변경해야 합니다.
이를 방지하려면 FXConverter 클래스가 App 클래스에 적응시키는 것이 필요해 종속성을 반전해야 합니다 .
이를 위해 인터페이스를 정의하고 FXConverter 클래스 대신 App에 종속되도록 합니다 . 그런 다음 인터페이스를 준수하도록 FXConverter를 변경합니다.
먼저 인터페이스 역할을 하는 추상 클래스 CurrencyConverter를 정의합니다. CurrencyConverter 클래스에는 모든 하위 클래스가 구현해야 하는 convert() 메서드 가 있습니다.
from abc import ABC
class CurrencyConverter(ABC):
def convert(self, from_currency, to_currency, amount) -> float:
pass
둘째, CurrencyConverter 클래스을 상속하기위해 FXConverter 클래스를 재정의하고 convert() 메서드를 구현합니다.
class FXConverter(CurrencyConverter):
def convert(self, from_currency, to_currency, amount) -> float:
print('Converting currency using FX API')
print(f'{amount} {from_currency} = {amount * 1.2} {to_currency}')
return amount * 2
셋째, __init__ 메서드를 App 클래스에 추가하고 통화 변환기의 개체를 초기화합니다.
class App:
def __init__(self, converter: CurrencyConverter):
self.converter = converter
def start(self):
self.converter.convert('EUR', 'USD', 100)
이제 App 클래스는 FXConverter 클래스가 아닌 CurrencyConverter 인터페이스에 의존합니다 .
다음은 FXConverter의 인스턴스를 만들어 App에 전달합니다.
if __name__ == '__main__':
converter = FXConverter()
app = App(converter)
app.start()
Output:
Converting currency using FX API
100 EUR = 120.0 USD
앞으로는 CurrencyConverter 클래스를 서브클래싱하여 다른 통화 변환기 API를 지원할 수 있습니다. 예를 들어, 다음은 CurrencyConverter에서 상속되는 AlphaConverter 클래스를 정의합니다.
class AlphaConverter(CurrencyConverter):
def convert(self, from_currency, to_currency, amount) -> float:
print('Converting currency using Alpha API')
print(f'{amount} {from_currency} = {amount * 1.2} {to_currency}')
return amount * 1.15
AlphaConvert 클래스는 CurrencyConverter 클래스에서 상속되므로 App클래스를 변경하지 않고도 App 클래스에서 해당 객체를 사용할 수 있습니다.
if __name__ == '__main__':
converter = AlphaConverter()
app = App(converter)
app.start()
Output:
Converting currency using Alpha API
100 EUR = 120.0 USD
전체 Code
from abc import ABC
class CurrencyConverter(ABC):
def convert(self, from_currency, to_currency, amount) -> float:
pass
class FXConverter(CurrencyConverter):
def convert(self, from_currency, to_currency, amount) -> float:
print('Converting currency using FX API')
print(f'{amount} {from_currency} = {amount * 1.2} {to_currency}')
return amount * 1.15
class AlphaConverter(CurrencyConverter):
def convert(self, from_currency, to_currency, amount) -> float:
print('Converting currency using Alpha API')
print(f'{amount} {from_currency} = {amount * 1.2} {to_currency}')
return amount * 1.2
class App:
def __init__(self, converter: CurrencyConverter):
self.converter = converter
def start(self):
self.converter.convert('EUR', 'USD', 100)
if __name__ == '__main__':
converter = AlphaConverter()
app = App(converter)
app.start()
Summary
- 종속성 반전 원칙을 사용하여 상위 수준 모듈을 구체적인 구현이 아닌 추상화에 종속되도록 하여 코드를 보다 강력하게 만듭니다.
'Python Object-oriented Programming' 카테고리의 다른 글
properties (0) | 2023.04.04 |
---|---|
__del__ Method (0) | 2023.04.04 |
__bool__ Method (0) | 2023.04.03 |
__hash__ Method (0) | 2023.04.03 |
__eq__ Method (0) | 2023.04.03 |
댓글