用于组合对象的设计模式

时间:2014-07-29 00:14:45

标签: python design-patterns refactoring

我有一个很难看的功能,我想重构一下。 原理上,该函数需要2个对象,访问几个 这些对象上的属性和方法,将它们组合起来并使用它们 组合结果以实例化结果对象。

看起来像这样:

def ugly(obj_a, obj_b):
    a_1 = obj_a.a_1
    sub_a_1 = obj_a.get_sub()
    r_1 = obj_b.combine(a_1)
    if r_1 < 0:
       raise ValueError
    if not sub_a_1.validate():
       raise Exception
    return ResultObj(a_1, r_1, sub_a_1.get_matrix(), obj_b.some_other_attribute)

除了在两者上访问许多属性和方法之外 对象以及传递给ResultObj的许多构造函数值。

此功能是单元/集成测试的噩梦。我站在那里 将不得不模拟obj_a和obj_b及其所有方法和 属性。

您对重构此类代码有何建议?理想情况下我 不必改变obj_a和obj_b的实现。

这是在Python中,所以OO和功能设计都有用。
谢谢

1 个答案:

答案 0 :(得分:1)

使这种程序代码更易于测试的一种方法是添加&#34; seams&#34;,即将代码分成可以单独运行的单元。很难回答你的问题,因为如果没有实际的代码,很难看到逻辑接缝。

您可以返回ResultObj的参数列表,而不是直接创建一个。这允许您测试过程而不是测试ResultObj。之后ResultObj(*args)很容易做到{{1}}。但是,你仍然处理很多价值观。

可能你可以有单独的功能分别访问和验证来自A和B的数据,然后返回简单的&#34; flat&#34;由第三个函数组合的数据结构(例如,namedtuple)。

除此之外,重构课程本身对我来说最有意义,尽管你说你宁愿避免它。如果创建A和B对象没有副作用或太多其他依赖项会有所帮助,但这又取决于您的特定代码。

还要考虑&#34;将两个对象组合成一个巨型对象&#34;本质上更多的是集成测试用例,而不是单元测试用例。