我很难用一种原则良好的面向对象的方式组织代码
总而言之:我希望有两个独立的类,每个类实现各自的功能(例如,分别模拟和绘图),但以某种方式将它们结合起来(以可扩展的方式!)让一个实例实现它们的两个功能
示例:假设我有一个生成数据的类
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
我还要绘制我的数据。我可以简单地向DataSimulator
添加一个plot()
方法,但是
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
李>类似地,我也认为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()
这解决了上面的第一个问题(我认为模拟器可以绘制数据,但绘图仪不能模拟数据),但是现在
DataPlotterVersion2
,我就不能重用DataSimulator
DataPlotter
中使用self.result
而不保证变量存在似乎也是不好的做法李>我的问题:
在我看来,我应该像您在第一个实现中提到的那样尽可能简单:两个独立的类。DataPlotter可以绘制任何类型的数据,而不仅仅是DataSimulator,因为python不检查可以传递任何其他对象的类型。唯一的限制是这个对象需要一个适合“plt.plot”函数的“result”属性
我认为这些方法都不是正确答案。模拟器是用来产生数据的,绘图仪是用来消耗和使用数据的。这里的数据是另一个对象。绘图仪不是模拟器,模拟器也不是绘图仪,理论上两者都不需要另一个存在,因此它们之间没有is-a或has-a关系。OOP旨在使用对象来表示您正在处理的实际事物。我甚至建议添加另一个数据类,即使它只是数组的包装器或类似的简单东西,模拟器类输出和绘图仪类作为输入
关于子弹 1.当然可以 2.如果它们紧密耦合,可以考虑使用数据管理器对象,而不是名为绘图仪或模拟器的对象,因为从思想上讲,它更接近于一个做两件事的对象,而不是两个做一件事的对象。如果需要v2,可以从中继承并覆盖进行打印/模拟的方法之一。 3,4,5,6.你是对的,这些都是坏主意,因为你所描述的原因
相关问题 更多 >
编程相关推荐