最佳实践方法,使两个耦合类中

2024-09-29 23:27:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我很难用一种原则良好的面向对象的方式组织代码

总而言之:我希望有两个独立的类,每个类实现各自的功能(例如,分别模拟和绘图),但以某种方式将它们结合起来(以可扩展的方式!)让一个实例实现它们的两个功能

示例:假设我有一个生成数据的类

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.我考虑让DataPlotterDataSimulator继承如下:

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而不保证变量存在似乎也是不好的做法

我的问题:

  1. 有解决这个问题的最佳实践方法吗(我在最上面的总结中写的是我真正想要的,还是我应该走一条完全不同的路?)
  2. 我提出的问题(在要点中)真的有效吗

Tags: 数据实例self功能plotinitdef方式
2条回答

在我看来,我应该像您在第一个实现中提到的那样尽可能简单:两个独立的类。DataPlotter可以绘制任何类型的数据,而不仅仅是DataSimulator,因为python不检查可以传递任何其他对象的类型。唯一的限制是这个对象需要一个适合“plt.plot”函数的“result”属性

我认为这些方法都不是正确答案。模拟器是用来产生数据的,绘图仪是用来消耗和使用数据的。这里的数据是另一个对象。绘图仪不是模拟器,模拟器也不是绘图仪,理论上两者都不需要另一个存在,因此它们之间没有is-a或has-a关系。OOP旨在使用对象来表示您正在处理的实际事物。我甚至建议添加另一个数据类,即使它只是数组的包装器或类似的简单东西,模拟器类输出和绘图仪类作为输入

关于子弹 1.当然可以 2.如果它们紧密耦合,可以考虑使用数据管理器对象,而不是名为绘图仪或模拟器的对象,因为从思想上讲,它更接近于一个做两件事的对象,而不是两个做一件事的对象。如果需要v2,可以从中继承并覆盖进行打印/模拟的方法之一。 3,4,5,6.你是对的,这些都是坏主意,因为你所描述的原因

相关问题 更多 >

    热门问题