拆分一个太大的类

时间:2012-02-06 04:36:57

标签: python class

我有一个类BigStructure,它从一些输入构建一个复杂的数据结构。它还包括对该数据结构执行操作的方法。

这个课程变得太大了,所以我试图把它分成两部分来帮助维护。我认为将这些操作转移到一个新的课程是很自然的,比如课程OperationsOnBigStructure

不幸的是,由于课程BigStructure非常独特,OperationsOnBigStructure无法与任何其他课程合理地重复使用。从某种意义上说,它永远与BigStructure联系在一起。例如,典型的操作可能包括以对BigStructure对象有意义的方式遍历大型结构实例。

现在,我有两个课程,但感觉我没有改进任何东西。事实上,我使事情稍微复杂一些,因为我现在需要将BigStructure对象传递给OperationsOnBigStructure中的方法,并且他们需要在内部存储该对象。

我应该和一个大班同学吗?

5 个答案:

答案 0 :(得分:5)

我想出的解决这个问题的方法是创建一个包含该类的包。 有点像:

MyClass/
    __init__.py
    method_a.py
    method_b.py
    ...

在我的情况下__init__.py包含实际的数据结构定义,但没有方法。要附加'类的方法我只是将它们导入到类中。命名空间。

method_a.py的内容:

def method_a(self, msg):
    print 'a: %s' % str(msg)

__init__.py的内容:

class MyClass():
    from method_a import method_a
    from method_b import method_b

    def method_c(self):
        print 'c'

在python控制台中:

>>> from MyClass import MyClass
>>> a = MyClass()
>>> dir(a)
['__doc__', '__module__', 'method_a', 'method_b', 'method_c']
>>> a.method_a('hello world')
a: hello world
>>> a.method_c()
c

这对我有用。

答案 1 :(得分:2)

  

我认为将操作移动到一个新类是很自然的,比如OperationsOnBigStructure类。

我想说,这与面向对象设计完全相反。 OOD背后的想法是将数据和方法保持在一起。

通常一个(太)大班是责任过多的标志:即你的班级只是做得太多了。您似乎首先定义了一个数据结构,然后向其添加了函数。您可以尝试将数据结构分解为子结构并为这些结构定义独立的类(即使用聚合)。但不知道更多,很难说......

当然,有时候,一个大班级的程序运行良好。但如果你自己觉得不舒服,那就是开始做某事的强烈暗示......

答案 2 :(得分:0)

  

例如,典型的操作可能包括遍历大型操作   结构实例只对BigStructure有意义   对象

也许你可以编写一些生成器作为BigStructure的方法来完成遍历的繁琐工作。然后,OperationsOnBigStructure可以在执行任务时循环遍历迭代器,这可能会提高代码的可读性。

因此,通过使用两个类而不是一个类,您将在两个阶段提高抽象级别。

答案 3 :(得分:0)

“”“现在,我有两个类,但感觉我没有改进任何东西。事实上,我使事情稍微复杂一些,因为我现在需要将BigStructure对象传递给OperationsOnBigStructure中的方法,并且他们需要在内部存储该对象。“”“

我认为一种自然的方法就是让“OperationsOnBigStructure”继承大结构 - 因此你将所有相关代码放在一个地方,而不需要额外的参数传递,因为它需要操作的数据将包含在“自我”。

答案 4 :(得分:0)

首先确保您拥有较高的测试覆盖率,这将提升您的重构体验。如果没有或没有足够的单元测试,请创建它们。

然后进行合理的小型重构步骤并保持单元测试工作:

根据经验,尝试将核心功能集中在大类中。如果耦合太多,请尽量不绘制边框。

首先将重构子任务分配给单独库中的函数。如果可以抽象,可以将该功能移到库中。

然后让代码更干净并重新排序,直到你可以看到它真正“想要”的结构。

如果最后你觉得你仍然可以在两个类中切割它,根据内部结构这是很自然的,那么考虑真的这样做。

始终保持测试覆盖率足够高,并在进行一些更改后始终重构。有一段时间你会有更漂亮的代码。