简体   繁体   English

如果场景的C ++代码重构

[英]C++ code refactoring for if scenario

I'm looking to refactor the c++ code for if conditions which will reduce the number of lines of code as well as it should have min complexity. 我正在寻找对c ++代码进行重构的条件,以减少代码行的数量,并且它应该具有最小的复杂度。

Here is the example: 这是示例:

if (xyz->a != cmd->aa)
{
   xyz->a = cmd->aa;
   obj->isFound = true;  //common code for all ifs
}


if (xyz->b != cmd->bb)
{
    xyz->b = cmd->bb;
    obj->isFound = true; 
}

And so on.. Here a, b, aa, bb are defined as a struct element. 依此类推..这里a,b,aa,bb被定义为struct元素。

Another example having if condition with arrays: 带有if条件与数组的另一个示例:

 if (abc->r16[0] != cmd->r0m)
    {
        abc>r16[0] = cmd->r0m;
        obj->isFound = true; //some common code for all ifs
    }


if (abc->r16[1] != cmd->r1m)
        {
            abc>r16[1] = cmd->r1m;
            obj->isFound = true; //some common code for all ifs
        }

And so on for r16[0] to r16[15]. 以此类推,对于r16 [0]至r16 [15]。 Here r16[15] is defined inside struct. r16 [15]在struct内部定义。

Last scenario is for if condition with multidimensional array: 最后一种情况是针对具有多维数组的if条件:

     if (pqr->c_0_15_r_0_15[0][0] != cmd->obj0000)
           {
              pqr->c_0_15_r_0_15[0][0] = cmd->obj0000
              obj->isFound = true; //some common code for all ifs
           }

if (pqr->c_0_15_r_0_15[1][0] != cmd->obj0100)
           {
              pqr->c_0_15_r_0_15[1][0] = cmd->obj0100
              obj->isFound = true; //some common code for all ifs
           }

if (pqr->c_0_15_r_0_15[2][0] != cmd->obj0000)
           {
              pqr->c_0_15_r_0_15[2][0] = cmd->obj0200
              obj->isFound = true; //some common code for all ifs
           }

Here c_0_15_r_0_15[2][0] will go through [0][0] to [15][0] and then [0][1] to [15][1] and so on... 在这里c_0_15_r_0_15 [2] [0]将经过[0] [0]至[15] [0],然后经过[0] [1]至[15] [1],依此类推...

For all such if condition scenario there will me 100's of if statements which should be reduced. 对于所有此类if条件场景,将减少100个if语句。 How can we refactor such code? 我们如何重构这样的代码?

First, find the duplication in your code. 首先,在您的代码中找到重复项。 As you already aware - the following scheme is duplicated many times: 如您所知-以下方案重复了很多次:

if (a != b)
{
    a = b;
    found = true;
}

So - encapsulate this in a function (template if there are multiple types: 所以-将其封装在一个函数中(如果有多种类型,则使用模板:

template <typename Dst, typename Src>
inline void updateIfNeeded(Dst& dst, const Src& src, bool& wasNeeded)
{
    if (dst != src)
    {
        dst = src;
        wasNeeded = true;
    }
}

See - how it helps: 请参阅-它如何帮助您:

updateIfNeeded(abc->r16[0], cmd->r0m, obj->isFound);
updateIfNeeded(abc->r16[1], cmd->r1m, obj->isFound);
// ...
updateIfNeeded(pqr->c_0_15_r_0_15[0][0], cmd->obj0000, obj->isFound);
updateIfNeeded(pqr->c_0_15_r_0_15[1][0], cmd->obj0100, obj->isFound);
// ...

So far - reduction is quite big - and it is much more readable what is going on in this code. 到目前为止-减少量很大-此代码中发生的事情更具可读性。


What I see more - obj->isFound is repeating many times - maybe - some encapsulation in a class this time: 我看到的更多obj->isFound重复了很多次-也许-这次在类中进行了一些封装:

class Updater
{
public:
    bool anyUpdateWasNeeded = false;

    template <typename Dst, typename Src>
    void  updateIfNeeded(Dst& dst, const Src& src)
    {
       if (dst != src)
       {
           dst = src;
           anyUpdateWasNeeded = true;
       }
   }
};

You see - not needed to pass obj->isFound so many times: 您看到-不需要多次传递obj->isFound

Updater upd;

upd.updateIfNeeded(abc->r16[0], cmd->r0m);
upd.updateIfNeeded(abc->r16[1], cmd->r1m);
// ...
upd.updateIfNeeded(pqr->c_0_15_r_0_15[0][0], cmd->obj0000);
upd.updateIfNeeded(pqr->c_0_15_r_0_15[1][0], cmd->obj0100);
// ...
obj->isFound = upd.anyUpdateWasNeeded;

Frankly, at this point I would consider to use preprocessor - I mean to shorten all these arrays update - this is because on left you have arrays - on right you have many fields of similar names ("indexed" names...?) 坦率地说,在这一点上,我将考虑使用预处理器-我的意思是缩短所有这些数组的更新-这是因为在左边有数组-在右边有许多相似名称的字段(“索引”名称...?)

But using preprocessor is bad style - let try to update arrays with pure C++: 但是使用预处理器是不好的样式-让我们尝试使用纯C ++更新数组:

class Updater
{
public:
    bool anyUpdateWasNeeded = false;

    template <typename Dst, typename Src>
    void  updateIfNeeded(Dst& dst, const Src& src);

    template <typename Dst, typename Src1, typename ...Src>
    void  updateArrayIfNeeded(Dst* dst, const Src1& src1, const Src& ...src)
    {
       updateIfNeeded(*dst, src1);
       updateArrayIfNeeded(dst + 1, src...);
   }
    template <typename Dst>
    void  updateArrayIfNeeded(Dst* dst) 
    {
        // nothing left
    }
};

So - this is what left: 所以-这就是剩下的:

upd.updateArrayIfNeeded(abc->r16, cmd->r0m, cmd->r1m, ....);
upd.updateArrayIfNeeded(pqr->c_0_15_r_0_15[0], cmd->obj0000, cmd->obj0001, ...);
upd.updateArrayIfNeeded(pqr->c_0_15_r_0_15[1], cmd->obj0100, ...);
// ...
obj->isFound = upd.anyUpdateWasNeeded;

And so on... 等等...

You can put it in some function, for a start: 您可以将其放在某个函数中作为开始:

template<typename Lhs, typename Rhs>
void flagSetIfNEq(Lhs & lhs, Rhs const & rhs, bool & flag) {
  if (lhs != rhs) {
    lhs = rhs;
    flag = true;
  }
}
// call it like
flagSetIfNEq(xyz->a, uvw->aa, obj->found)!

I'm assuming that found in your code is of type bool . 我假设在您的代码中found的类型是bool

Though if you have that "100s of times" in your code you probably should consider a more aggressive refactoring. 尽管如果您的代码中有“ 100倍的次数”,您可能应该考虑进行更积极的重构。

And give that function a better name. 并给该函数起一个更好的名字。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM