2

虽然我用 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,这有点多余?

我只是在这里进退两难。到目前为止,我无法说服自己使用其中一个。

大家更喜欢哪一个,有什么理由吗?

4

3 回答 3

6

这种技术的花哨的词是缓存:你计算一次两个距离的引用,并将它缓存在对象中。一般来说,缓存可以让你用计算机内存“付费”来加速你的计算。

如果分析器告诉您,您的代码在重复调用 时花费了大量时间m_a->h1()->h2(),这可能是一种合理的优化,前提是h1and的返回值h2永远不会改变。但是,在没有先进行分析的情况下进行这样的优化几乎总是过早优化的不良信号。

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

于 2012-12-17T02:15:22.620 回答
0

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

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

于 2012-12-17T02:19:26.407 回答
0

Whenever I have something like this I usually store m_a->h1() into a variable with a meaningful name at function scope since it's likely to be used again later in function's body.

于 2012-12-17T07:09:02.390 回答