开发者

Code Brain "Teaser" -- but not really

I'm just curious to开发者_Go百科 see what you guys think about this. I heard a bunch of answers passed around the office and I want to see if you guys can have possibly a better one.

Question:

You have two functions outlined below:

function one()
{
    A();
    B();
    C();
}

function two()
{
    A();
    D();
    C();
}

How would you re-write this (anything counts, you could create classes, variables, other methods, anything), to reduce code duplication?

Each of the methods called changes variables that the other functions need to use. Methods A() B() and C() are already defined.


Not all languages will support this approach, and the syntax of passing a function may vary between those that do, but the concept would be:

function one()
{
    refactored(B);
}

function two()
{
    refactored(D);
}

function refactored(middleMan)
{
    A();
    middleMan();
    C();
}


There is no code duplication here. It looks fine.


Each of the methods called changes variables that the other functions need to use.

I would start by refactoring the entire class to use proper OOP.


There are a number of ways to refactor that code; which I would use depends on the specific application, as it may mean that I need to reconsider things at a higher level, e.g. redefine classes, or at worst review the entire application design because the duplication means I missed some key relationship.


If your functions one() and two() are really three-liners as in the example, I wouldn't rewrite anything. You would loose readability and make the code much harder to understand for the next guy.

If the calls to A() and C() are actually larger blocks of code... - define a base class with abstract method X() and a concrete function any() { A(); X(); C(); }

  • define a class One where X() is implemented by B()
  • define a class Two where X() is implemented by D()


Here's one option.

function (triggerA, triggerB, triggerC, triggerD)
{
     A(triggerA);
     B(triggerB);
     C(triggerC);
     D(triggerD);
}

This way you're only calling one function to do it all, and skips whatever you don't need/want to do.


If you have closures, lambdas etc. available, you could write

function one()
{
    three(B)
}

function two()
{
    three(D);
}

function three(middle) 
{
    A();
    middle();
    C();
}


You could (but probably shouldn't) make a class where A() is the constructor and C() is the destructor, and have one() and two() be methods of the class calling B() and D() respectively.

I said you probably shouldn't because OOP should be used to write code that makes sense and not for obscure optimization reasons.


In C++ this is usually accomplished with RAII if the context makes sense... this pattern is usually A() = some init function, C() = some de-init function. There's usually also a context associated that's being initialized or destroyed as well.

   class bar
    {
        bar() {
            A();
        }

        ~bar() {
            C();
        }
    };

    void one() 
    {
        bar barvar;
        B();
    }

    void two()
    {
        bar barvar;
        D();
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜