【问题标题】:Design pattern for combining objects组合对象的设计模式
【发布时间】:2014-07-29 00:14:44
【问题描述】:

我有一个非常丑陋的函数,我想重构它。 示意性地,该函数需要 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 中,所以面向对象和函数式设计都可以工作。
谢谢

【问题讨论】:

    标签: python design-patterns refactoring


    【解决方案1】:

    使这种程序代码更易于测试的一种方法是添加“接缝”,即将代码拆分为可以单独运行的单元。很难抽象地回答你的问题,因为没有实际代码很难看到逻辑接缝。

    您可以返回 ResultObj 的参数列表,而不是直接创建一个。这允许您测试流程而不是同时测试 ResultObj。之后很容易做到ResultObj(*args)。但是,您仍然需要处理很多值。

    您可能有单独的函数来分别访问和验证来自 A 和 B 的数据,然后返回由第三个函数组合的简单“平面”数据结构(例如 namedtuple)。

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

    还要考虑“将两个对象组合成一个大型对象”本质上更像是一个集成测试用例,而不是一个单元测试用例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-22
      • 2011-06-30
      • 2016-11-23
      • 1970-01-01
      • 2012-05-20
      相关资源
      最近更新 更多