Mat*_*agé 5 c++ oop algorithm refactoring
我有一种方法,其中性能非常重要(我知道过早的优化是所有邪恶的根源.我知道我应该并且我确实对我的代码进行了描述.在这个应用程序中,每十分之一秒我保存是一个很大的胜利.)这种方法使用不同的启发式方法来生成和返回元素.试探法被用来顺序地:所述第一试探法使用,直到它不再返回元件,则第二试探法使用直到它可以直到所有启发式已经使用不再返回元件等.在方法的每次调用中,我使用开关移动到右侧启发式.这很难看,但效果很好.这是一些伪代码
class MyClass
{
private:
unsigned int m_step;
public:
MyClass() : m_step(0) {};
Elem GetElem()
{
// This switch statement will be optimized as a jump table by the compiler.
// Note that there is no break statments between the cases.
switch (m_step)
{
case 0:
if (UseHeuristic1())
{
m_step = 1; // Heuristic one is special it will never provide more than one element.
return theElem;
}
m_step = 1;
case 1:
DoSomeOneTimeInitialisationForHeuristic2();
m_step = 2;
case 2:
if (UseHeuristic2())
{
return theElem;
}
m_step = 3;
case 3:
if (UseHeuristic3())
{
return theElem;
}
m_step = 4; // But the method should not be called again
}
return someErrorCode;
};
}
Run Code Online (Sandbox Code Playgroud)
正如我所说,这是有效的,并且它是有效的,因为在每次调用时,执行跳转到它应该的位置.如果启发式不能提供一个元素,m_step递增(所以,下一次我们不要再尝试这种启发式),并因为没有break语句,接下来的试探法尝试.另请注意,某些步骤(如步骤1)永远不会返回元素,而是为下一个启发式进行一次初始化.
初始化并非全部预先完成的原因是它们可能永远不需要.GetElem在返回元素后不会再次被调用是可能的(也是常见的),即使它仍然可以返回元素.
虽然这是一个有效的实现,但我发现它真的很难看.案件陈述是一个黑客; 使用它不间断也是hackish; 即使每个启发式方法都封装在自己的方法中,该方法也会变得非常长.
我应该如何重构这些代码,使其更具可读性和优雅性,同时尽可能保持高效?
在我看来,如果您不需要对这段代码进行太多修改,例如添加新的启发式方法,那么就很好地记录它并且不要碰它。
但是,如果添加和删除了新的启发式方法,并且您认为这是一个容易出错的过程,那么您应该考虑重构它。为此,显而易见的选择是引入状态设计模式。这将用多态性替换您的 switch 语句,这可能会减慢速度,但您必须对两者进行分析才能确定。