将State传递给函数而不是在类实例上调用方法

时间:2017-02-10 21:36:07

标签: python oop refactoring

我已经开始研究一些有点遗留的代码库,将其更新为Python 3.构建此代码的设计人员/工程师决定将它们组合成一个设置,而不是完整的OOP或全功能。主业务逻辑在作为数据结构和类实例的单个对象上执行:

class StateHolder:
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def method_one(self, x, y):
        self.a = a + x
        self.b = b + y


def modify_c(state_holder, new_c):
    state_holder.c += new_c

def main():
    example = StateHolder(1, 2, 3)
    example.method_one(4, 5)
    modify_c(example, 6)

modify_c这样的函数数量远远超过了类中的方法,所以它并不像我在这里看到的那么简单。具体来说,一次只有StateHolder个实例,并且所有方法都直接对其进行操作,而不是创建新副本并将其传回。

我的问题是:如果我有无限的时间来重构这个,我应该遵循哪个系统来构建和保存数据?我应该将modify_c等所有功能移到StateHolder中,还是应该将所有StateHolder方法移出并传递状态?

2 个答案:

答案 0 :(得分:1)

我建议进入OO方向。特别要查找系统中存在的其他对象。在任何复杂程序中只有一个对象是很少见的。首先拉出较小的物体。

答案 1 :(得分:1)

从你描述的代码库和给定的时间,你应该尝试使用面向对象编程(OOP)方法重构代码。

<强>为什么吗

如果你打算使用OOP,那么至少要做正确的事!

除此之外,OOP的特点是具有以下内容的对象:

  1. 状态:一个可变的状态,它将代表对象包含的信息。
  2. 封装:将类似信息捆绑在一起相同的项目/对象的想法。
  3. 数据隐藏:提供保护您的数据的方式与外界隔离。通过这种方式,对象的状态被隐藏起来,不能随意操纵(不要与“封装”混淆)。
  4. 遵循以下定义:

    函数modify_c违反了封装和数据隐藏。有关对象状态的信息遍布整个地方,可以从外部世界(函数)修改信息。

    • 以前的设计师做出了错误的决定,将不同的方法混合在一起,可以完全包含在课程StateHolder中。

    • 定义类并实例化它们的关键是创建表示具有某种当前状态(使用属性定义)和常见行为的元素的模型(使用方法定义)可以修改模型的状态。更改对象状态的责任应该依赖于类本身(即使用get / set方法)。

    • 您自己提到该对象的单个实例存在。因此,StateHolder非常适合应用经典Singleton设计模式,其中StateHolder的单个实例将在运行时存在。这样,将保留相同的状态,并且在调用对象时不必传递。

    如果您重构代码,那么实现纯粹的OOP解决方案会更加清晰,可维护,可重用和可扩展。将StateHolder作为类,实例化为Singleton对象。

    关于OOP的进一步阅读:

    SOLID。面向对象编程和设计的五个基本原则。对于您的解决方案,请特别关注SRP(单一责任原则)和OCP(开放式原则)。所以答案是 YES 并将这些方法添加到课程中!