Context
据我所知,SOLID OOP的依赖反转和接口隔离原则告诉我们根据interface编写程序,而不是内部细节.因此,我试图用Python开发一个简单的股票市场数据收集器,大致使用下面的对象图,其中main
封装了应用程序业务逻辑、用户输入处理等.
- 粉红色代表具体的函数或类,绿色代表抽象类
- 空心箭头表示/实现关系的子类,实心箭头表示using关系(遵循Robert Martin的Clean Architecture约定)
因此,Main函数使用抽象接口,该接口根据符号获取股票价格.该抽象类如下所示
#!/usr/bin/env python3
# encoding: utf-8
"""
Defines the abstract stock price reader
"""
from abc import ABC, abstractmethod
class StockPriceReader(ABC):
"""Defines the general tick reader interface."""
@abstractmethod
def get_price(self, symbol:str)->float:
"""
Gets the price of a stock represented by the symbol, e.g
when symbol='AAPL', it gets the Apple Inc stock price.
"""
raise NotImplementedError
TickReaderConcrete
类实现了内部细节,并通过类似于Bloomberg或交易所API调用的方式获取实际股票价格.进行API调用所需的凭据必须是内部细节的一部分.这里没有显示代码,因为它很容易实现.
Dilemma
现在,基于上面简单的类依赖关系图,同一本书(Clean Architecture)似乎暗示(这里我强调)
主块应该not even be aware表示TickReaderConcrete存在.
至少,这是我对这本书所说的,因为没有箭头从main
到TickReaderConcrete
,纠正我,如果我错了.
但是当我写main.py
时,我不能假装TickReaderConcrete
不存在,换句话说,main
似乎忍不住知道TickReaderConcrete
的存在,当代码看起来像
#!/usr/bin/env python3
# encoding: utf-8
"""
The main function to invoke the stockprice reader
"""
from tickreader import TickReaderConcrete
...
if __name__ == '__main__':
# This line gives rise to the alternative class diagram below
reader=TickReaderConcrete(...)
# After initialised, we can use the interface permitted by the abstract base class
reader.get_price(symbol='IBM')
Question
那么,如何确保main
人不知props 体读者的存在呢?如果main
根本不导入具体阅读器,它甚至不能实例化具体阅读器对象,抽象阅读器无论如何都不能初始化.
那么,如何基本上组织代码来正确实现上面的对象图呢?
Slightly Paraphrased Question
即使抽象基类公开了必要的公共方法,至少initialisation也需要知props 体子类的存在.具体子类能隐藏在抽象基类后面吗?请看另一个对象图,这是上面代码片段实现的.如何摆脱 break line ?