我试图通过this tutorial中一些简单但具体的代码和类(用Python实现)来理解依赖反转原理(DIP).我(用我自己的 comments 和理解)对此进行了总结,以节省您经历整个过程的痛苦.
基本上,我们正在构建一个货币转换器应用程序,其中我们将main应用程序逻辑与货币转换器本身分开.代码(一些注释和我的文档字符串)如下所示.
Snippet 1
#!/usr/bin/env python3
# encoding: utf-8
"""Currency converter application using some exchange API."""
class FXConverter:
"""The converter class."""
def convert(self, from_currency, to_currency, amount):
"""
Core method of the class. Assume the magic number 1.2 is from some API like
Oanda
"""
print(f'{amount} {from_currency} = {amount * 1.2} {to_currency}')
return amount * 1.2
class App:
"""The Application"""
def start(self):
"""The main method to create and invoke the converter object."""
converter = FXConverter()
converter.convert('EUR', 'USD', 100)
if __name__ == '__main__':
app = App()
app.start()
现在,教程声称(直接引用)
future ,如果FX的API发生变化,它将破解代码.此外,如果您想使用不同的API,则需要更改App类.
所以他们提出了这一点.
Snippet 2
#!/usr/bin/env python3
# encoding: utf-8
"""Currency converter application using dependency inversion."""
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.2 # The tutorial seems to have a typo here.
class App:
def __init__(self, converter: CurrencyConverter):
self.converter = converter
def start(self):
self.converter.convert('EUR', 'USD', 100)
if __name__ == '__main__':
converter = FXConverter()
app = App(converter)
app.start()
Question
在我看来,这句话听起来并不真实,这切中了我为什么不能理解股市下跌的核心原因.即使FXConverter
使用不同的交易所API(假设彭博而不是Oanda),这种变化不会局限于convert
方法吗?只要convert
方法维护签名
convert(str, str, float)->float # The strings must be valid currency names
这App.start
人应该是幸福的.维护此有效方法签名的必要性是
- 即使是在浸渍版中也没有被go 除.
- 在更安全的语言(如Rust或C++)中自动强制执行.在更严格的语言中,我可能会列举可能的货币范围,以确保字符串变量不是像US$或£等这样的自由形式.
这就是为什么我根本看不出DIP如何有助于更好地解耦,而我们实际上需要的是遵守静态类型语言中的函数/方法签名?
通常,当A
调用B
(对象方法或函数等)时,我们能假定
-
A
不知道B
的内部工作原理 -
B
不知道A
对结果做了什么
以便自动实施所需的脱钩?