У меня возникают проблемы с организацией моего кода в принципиальной объектно-ориентированной форме.
В итоге : я хотел бы иметь два отдельных класса, каждый из которых реализует свою собственную функциональность (например,моделирование и построение графиков, соответственно), но каким-то образом объединить их (расширяемым образом!), чтобы один экземпляр реализовал обе их функциональности.
Пример: предположим, у меня есть класс, который генерирует данные
class DataSimulator():
def __init__(self, N):
self.N = N
self.result = None
def simulate(self):
self.result = range(self.N) #imagine lots of simulation code here
Я также хотел бы построить свои данные.Я мог бы просто добавить plot()
метод к DataSimulator
, но
- Я думаю, что
DataPlotter
должен быть отдельным отдельным классом, так как его функциональность полностью отличается от DataSimulator
.
A. Один из вариантов, который я придумал, - это отдельный класс, который хранит экземпляр DataSimulator
, а затем строит его при необходимости
class DataPlotter():
def __init__(self, data_simulator_instance):
self.d = data_simulator_instance
def plot(self):
plt.plot(self.d.result) #e.g. using matplotlib
dataSim = DataSimulator(5)
dataPlt = DataPlotter(dataSim)
dataSim.simulate()
dataPlt.plot()
Однако, чтобы использовать эту парадигму,
- Мне нужно всегда отслеживать два отдельных тесно связанных объекта.Это похоже на плохую практику.У меня никогда не будет одного без другого, поэтому я хотел бы объединить их функциональность в одно.
B. Я подумал о том, чтобы наследовать DataPlotter
от DataSimulator
, вот так:
class DataPlotter(DataSimulator):
def plot(self):
plt.plot(self.result)
dataPlt = DataPlotter(5)
dataPlt.simulate()
dataPlt.plot()
Это хорошо, потому что я сейчасесть только один экземпляр, который делает все, что мне нужно, но это все равно кажется неправильным, потому что:
- сбивает с толку тот факт, что экземпляр
DataPlotter
выполняет процедуру моделирования - Если я пишу
DataSimulatorVersion2
, я не могу повторно использовать DataPlotter
.
C. Точно так же я также считал DataSimulator
наследовать от DataPlotter
class DataPlotter():
def plot(self):
plt.plot(self.result)
class DataSimulator(DataPlotter):
def __init__(self, N):
self.N = N
self.result = None
def simulate(self):
#lots of simulation code here
self.result = range(self.N)
dataSim = DataSimulator(5)
dataSim.simulate()
dataSim.plot()
Это решает первую проблему, описанную выше (я думаю, что для симулятора имеет смысл отображать свои данные, но не для плоттера для имитации данных), но теперь
- Я могуповторное использование
DataSimulator
, если я напишу DataPlotterVersion2
- Использование
self.result
в DataPlotter
без какой-либо гарантии, что переменная существует, также кажется плохой практикой.
Мой вопрос:
- Существует ли наилучший способ решения этой проблемы?(Является ли то, что я написал в сводке вверху, действительно тем, что я хочу, или я должен пойти совершенно другим путем?)
- Действительно ли проблемы, которые я поднял (в пунктах с маркерами), действительно актуальны?