我有一个类BigStructure
,它从一些输入构建一个复杂的数据结构。它还包括对该数据结构执行操作的方法。
这个课程变得太大了,所以我试图把它分成两部分来帮助维护。我认为将这些操作转移到一个新的课程是很自然的,比如课程OperationsOnBigStructure
。
不幸的是,由于课程BigStructure
非常独特,OperationsOnBigStructure
无法与任何其他课程合理地重复使用。从某种意义上说,它永远与BigStructure
联系在一起。例如,典型的操作可能包括以对BigStructure
对象有意义的方式遍历大型结构实例。
现在,我有两个课程,但感觉我没有改进任何东西。事实上,我使事情稍微复杂一些,因为我现在需要将BigStructure
对象传递给OperationsOnBigStructure
中的方法,并且他们需要在内部存储该对象。
我应该和一个大班同学吗?
答案 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)
首先确保您拥有较高的测试覆盖率,这将提升您的重构体验。如果没有或没有足够的单元测试,请创建它们。
然后进行合理的小型重构步骤并保持单元测试工作:
根据经验,尝试将核心功能集中在大类中。如果耦合太多,请尽量不绘制边框。
首先将重构子任务分配给单独库中的函数。如果可以抽象,可以将该功能移到库中。
然后让代码更干净并重新排序,直到你可以看到它真正“想要”的结构。
如果最后你觉得你仍然可以在两个类中切割它,根据内部结构这是很自然的,那么考虑真的这样做。
始终保持测试覆盖率足够高,并在进行一些更改后始终重构。有一段时间你会有更漂亮的代码。