我无法以面向对象的原则组织我的代码。
总结:我希望有两个单独的类,每个类都实现自己的功能(例如分别进行模拟和绘图),但不知何故将它们(以可扩展的方式!)组合成一个实例实现它们的两个功能。
示例:假设我有一个生成数据的类
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
而不保证变量存在也似乎是不好的做法。 我的问题:
答案 0 :(得分:1)
我认为列出的这些方法都不是正确的答案。模拟器用于生成数据,绘图仪旨在使用和使用它 - 数据是此处的另一个对象。绘图仪不是模拟器,模拟器不是绘图仪,理论上它们都不需要另一个存在,因此它们没有is-a或has-a关系。 OOP旨在使用对象来表示您正在使用的实际内容。我建议添加另一个Data类,即使它只是一个数组的包装器或类似的简单,你的模拟器类输出和你的Plotter类作为输入。
关于子弹 - 是的,当然 2.如果它们是紧密耦合的,考虑使用一个数据管理器的对象而不是一个名为绘图仪或模拟器的对象,从意识形态来说,它将更接近于一个对象做两件事而不是两件做一件事。如果你需要一个v2,你可以继承它并覆盖其中一个进行绘图/模拟的方法。 3,4,5,6。你是对的,出于你所描述的原因,这些都是坏主意。
答案 1 :(得分:0)
在我看来,我会像你在第一次实现中提到的那样尽可能简单:两个分开的类。 DataPlotter不仅可以绘制任何类型的数据DataSimulator,因为python不会检查您可以传递任何其他对象的类型。唯一的限制是这个对象需要一个'结果'适合' plt.plot'功能