I'm computer engineering student who is new in the realm of design patterns, for some reason I started with Dependency inversion- higher level policy should not depend on lower-level policy, but should depend on abstraction.
so to apply that concept, I refactored some code in my application so that the inputs to my application are flexible and easily changeable, my application, for now, can get assets prices either using real-time data or static data stored inside a file, here is the code:
class PricesData(ABC):
@abstractmethod
def get_data(self):
pass
class ApiOrMockPricesData(PricesData):
def __init__(self,assets_tickers:list[str]):
self.assets_tickers=assets_tickers
self.is_default=False
def get_data(self)->tuple[bool,pd.DataFrame]:
data:pd.DataFrame = robust_download(self.assets_tickers)
if data is None:
print("[WARNING] Using fallback data")
self.is_default=True
data=pd.read_parquet("historical_prices.parquet")
return self.is_default,data
class MockData(PricesData):
def __init__(self):
self.is_default=True
def get_data(self)->pd.DataFrame:
return self.is_default,pd.read_parquet("historical_prices.parquet")
#I can add any other classes I want to represent some input.
class HistoricalPricesService:
def __init__(self, data_source: PricesData):
self.data_source = data_source
def get_data(self)->tuple[bool,pd.DataFrame]:
return self.data_source.get_data()
first_service=HistoricalPricesService(ApiOrMockPricesData(assets_tickers=assets_tickers[0:10]))
is_default,prices=first_service.get_data()#this method call never changes regardless of the underlying implmentation.
so I came to the conclusion that DIP will make my life easier because inputs may change in the future, so I should always use DIP, is this always true?