How to avoid code duplication?

Can code duplication be avoided in such cases? (Java code)

void f()
{
    int r;
    boolean condition = true;
    while(condition)
    {
        // some code here (1)

        r = check();
        if(r == 0)
            break ;
        else if(r == 1)
            return ;
        else if(r == 2)
            continue ;
        else if(r == 3)
            condition = false;

        // some code here (2)

        r = check();
        if(r == 0)
            break ;
        else if(r == 1)
            return ;
        else if(r == 2)
            continue ;
        else if(r == 3)
            condition = false;

        // some code here (3)
    }
    // some code here (4)
}

int check()
{
    // check a condition and return something
}

A possible solution might be to use Exceptions, but this does not seem to be good practice. Is there a so-called good program flow control model in such cases? For example, a method of calling break ;from within a function check(). (Perhaps in other programming languages)

+5
source share
6 answers

Some good answers (especially @Garrett just now) to the tricky question, but I will add my $ 0.02 for posterity.

There is no simple answer on how to reorganize this block without seeing the actual code, but my reaction to it is that it needs to be redesigned.

, break; check(). (, )

, Java ( ) check(), / , . :

  • some code here -. , ?

  • , . , , , .

  • , , ? , , , , .

, @aix , - . , , .

, . , switch, . . , - :

int state = 0;
WHILE: while(true) {
    switch (state) {
       case 0:
            // 1st some code here
            state = 1;
            break;
       case 1:
            state = check();
            break;
       case 2:
            return;
       case 3:
            break WHILE;
       case 4:
            // 2nd some code
            state = 1;
            break;
        ...
    }
 }

, .

+4

- , .

// some code here , , - . , .

+2

, aix: ! . , break, continue return , .

, ,

private int r;
void f()
{
    distinction({void => codeBlock1()}, {void => codeBlock4()}, {void => f()}, 
      {void => distinction( {void => codeBlock2()},{void => codeBlock4()},
                            {void => f()}, {void => codeBlock3()} )
      });
}

void distinction( {void=>void} startingBlock, {void=>void} r0Block, {void=>void} r2Block, {void=>void} r3Block){ 
        startingBlock.invoke();
        r = check();
        if(r == 0)
            r0Block.invoke();
        else if(r == 1)
            {}
        else if(r == 2)
            r2Block.invoke(); 
        else if(r == 3)
            // if condition might be changed in some codeBlock, you still
            // would need the variable condition and set it to false here.
            r3Block.invoke();
}

. , r0Block r2Block , codeBlock4() f() (). () f(). Java <= 7 invoke(), 4 codeBlock1 - codeBlock4. , , , - codeBlocks break/return/continue-orgy.

+1

. ( ). Switch. .

0

One of the best ways to do this would be to use switch statements, something like this:

void f()
{
int r;
boolean condition = true;
while(condition)
{
outerloop:


    r = check();
    switch(r){

    case 0: break outerloop;

    case 1: return;

    case 2: continue;

    case 3: condition  = false;


}
0
source

You might want to think about re-formulating your logic as a finite machine. This can simplify the situation and probably simplify the logic.

0
source

All Articles