你会创建一个私有类成员来消除多级函数调用吗?

时间:2012-12-17 02:11:01

标签: c++ oop refactoring

虽然我用C ++编写了这个例子,但这个代码重构问题也适用于任何支持OO的语言,例如Java。

基本上我有A级

class A
{
public:
  void f1();
  void f2();
  //..
private:
  m_a;
};

void A::f1()
{
  assert(m_a);
  m_a->h1()->h2()->GetData();
  //..
}

void A::f2()
{
  assert(m_a);
  m_a->h1()->h2()->GetData();
  //..
}

你们会创建一个持有指针m_f的新私有数据成员m_a->h1()->h2()吗?我能看到的是它有效地消除了多级函数调用,这确实简化了代码。

但从另一个角度来看,它创建了一个“不必要的”数据成员,可以从另一个现有的数据成员m_a中推导出来,这有点多余?

我刚刚陷入两难境地。到目前为止,我无法说服自己使用其中一个。

你们更喜欢哪个?

3 个答案:

答案 0 :(得分:6)

这种技术的奇特之处是缓存:你计算一次两次引用,并在对象中缓存。通常,缓存允许您“支付”计算机内存以加快计算速度。

如果分析器告诉您代码在重复调用m_a->h1()->h2()时花费了大量时间,那么这可能是合法的优化,前提是h1和{{的返回值1}}永远不会改变。但是,在没有首先进行分析的情况下进行这样的优化几乎总是一个过早优化的坏迹象。

如果性能不是问题,一个好的规则是远离存储可以从存储在对象中的其他成员计算的成员。如果您想提高清晰度,可以引入一个名称很好的方法(成员函数)来计算两个引用的引用而不存储它。只有在对性能至关重要的罕见情况下,存储才有意义。

答案 1 :(得分:0)

我不会。我同意这只是你设计的例子中的事情,但那是因为m_a->h1()->h2()没有固有的含义。在设计良好的应用程序中,使用的方法名称应该告诉您有关正在进行的调用的定性,并且应该是自我记录代码的一部分。我认为,在设计合理的代码中,m_a->h1()->h2()应该更易于阅读和理解,而不是重定向到为您调用它的私有方法。

现在,如果m_a->h1()->h2()是一项昂贵的调用,需要花费大量时间来计算结果,那么您可能会有一个用于缓存的参数,如@dasblinkenlight建议的那样。但是为了一些按键而抛弃方法调用的描述性是不好的。

答案 2 :(得分:0)

每当我有这样的东西时,我通常会将m_a-> h1()存储到一个在函数范围内具有有意义名称的变量中,因为它可能会在函数体的后面再次使用。