在不牺牲效率的情况下保持代码干燥

时间:2016-12-17 02:17:02

标签: c++ dry

假设我有两个几乎完全相同的函数,它们代表了系统的瓶颈,看起来像这样,(更复杂):

void f1( int s )
{
    for( size_t i = 0, END = m_v.size(); i < END; ++i )
    {
        int bin_id = binId( m_v[ i ], s );
        m_result[ bin_id ] += m_w[ i ]; //
    }
}

void f2( int s )
{
    for( size_t i = 0, END = m_v.size(); i < END; ++i )
    {
        int bin_id = binId( m_v[ i ], s );
        m_result[ bin_id ] += 1.f; //
    }
}

除了在代码的一行中使用变量或常量之外,一切都是相同的。如上所述,假设实际代码要复杂得多。如果没有与次要差异重复两次将是很好的,因为它需要一个确保每个相同的维护。我可以做这样的事情将它们合并为一个:

void f3( bool use_weight, int s )
{
    if( use_weight )
    {
        for( size_t i = 0, END = v.size(); i < END; ++i )
        {
            int bin_id = binId( v[ i ], s );
            result[ bin_id ] += m_w[ i ]; //
        }
    }
    else 
    {
        for( size_t i = 0, END = v.size(); i < END; ++i )
        {
            int bin_id = binId( v[ i ], s );
            result[ bin_id ] += 1.f; //
        }
    }
}

但这仍然是在一个函数内复制代码。我们可以这样做,但会带来更糟糕的表现:

void f3( bool use_weight, int s )
{
    for( size_t i = 0, END = v.size(); i < END; ++i )
    {
        int bin_id = binId( v[ i ], s );
        if( use_weight )
        {
            result[ bin_id ] += m_w[ i ]; //
        }
        else 
        {
            result[ bin_id += 1.f; //
        }
    }
}

调用代码如下所示:

bool use_weight = something.use_weight();
const int N = very_large_number;
for( int s = 0; s < N; ++s )
{
    f3( use_weight, s );
}

同样,假设代码更加复杂,例如f3实际上是复制了很多逻辑。

1 个答案:

答案 0 :(得分:1)

老实说,有时优化代码可重用性通常可以解决问题,但在您的示例中,利用多态性可能会更好。类和函数应该接受它们正在处理的参数而不是工作成员变量。制作一个“超级”功能或“完成所有”的课程通常是一个错误。随着时间的推移,这些类和函数变得越来越臃肿。

因此,代码理想情况下将使用接口,并且将注入所需的解析器。 :)

var parser1 = new HotSauceParser();
parser.parse(arrayData);

var parser2 = new WeightParser();
parser2.setWeights(m_w); // in many langages you can chain this.
parser.parse(arrayData);

这跟在Single responsibility principle之后,很容易测试。然后你可以编写一个类来决定何时使用一个类或另一个类。 HOW解析的逻辑封装在解析器本身中。

就效率而言,通常如果您正在解析数组,性能问题是关于该数组是如何BIG以及您是否必须遍历整个结构。

请注意“干掉”代码,很容易过度干掉代码,并陷入常见的陷阱,例如过度使用继承和/或使用“功能羡慕”创建类和函数。

您可能需要查看清洁代码一书和 S.O.L.I.D。