4

I'm currently implementing an algorithm that constructs a matrix-pattern based on mathematical formulas. To achieve this I use deeply nested for-loops and alot of if-conditions in it. The problem is, that I cannot split the loop into multiple method without providing a lot of parameters. And for now the code looks like an undesired spaghetti-code.

Here is a small pseudo-example:

int steps = 10;

void evaluate( int numOuterArea , int numInnerArea , int[] solution , int[] factor , int[] indices )
{
  int counterA = 0;
  int counterB = 0;

  for( int outerAreaIter = 0 ; outerAreaIter < numOuterArea ; outerAreaIter++ )
  {
    for( int curOuterAreaIter = 0 ; curOuterAreaIter < steps ; curOuterAreaIter++ )
    {
      for( int innerAreaIter = 0 ; innerAreaIter < numInnerArea ; innerAreaIter++ )
      {
        for( int curInnerAreaIter = 0 ; curInnerAreaIter < curOuterAreaIter ; curInnerAreaIter++ )
        {
          if( curInnerAreaIter == curOuterAreaIter )
          {
            // do something with solution, factor or indices
          }
          else if( /* some other fancy condition */)
          {

          }
          ...
        }
      }
    }
  }

  // similar nested loops follow here
}

If I would write classes/methods for each loop or part of a loop, I have to provide all parameters from evaluate() (which can be even more as shown in the example) and also all previous iterators and possible variables.

Is there a way/common practice/any hints or advice to rewrite such code in a better way?

2
  • @Buni Are the for loops themselves always the same? with only the code block of the inner most for loop changing? Commented Aug 20, 2014 at 8:41
  • No, the loops change several times in different evaluate()functions and also inside the functions there are several different implementations. Also the conditions, variables and so on change every time. Commented Aug 20, 2014 at 8:59

2 Answers 2

2

The simplest way is encapsulation of all parameters in the single object. You can use this object to passing data as sole parameter into evaluation method. Something like this example:

class EvaluationContext {
    int numOuterArea;
    int numInnerArea;
    int[] solution;
    int[] factor;
    int[] indices;
}

interface Evaluator {
    void evaluate(EvaluationContext ctx); 
}

class FirstEvaluator implements Evaluator {
    void evaluate(EvaluationContext ctx) {
        SecondEvaluator e2 = new SecondEvaluator(); 
        for (...) {
            e2.evaluate(ctx);
        }
    }
}

class SecondEvaluator implements Evaluator {
    void evaluate(EvaluationContext ctx) {
        // evaluate something and put result into context
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1

A simple design pattern is a Method Object. Simply write a class which is responsible for this calculation. You then can have fields that simply store intermediate results during that calculation. With this approach, you do not need to pass any arguments.

Example:

class EvaluateMethod {
    private final int numOuterArea;
    private final int numInnerArea;
    private final int[] solution;
    private final int[] factor;
    private final int[] indices;

    // place fields for intermediate results here

    EvaluateMethod(int numOuterArea, int numInnerArea, int[] solution, int[] factor, int[] indices) {
        // assign all parameter to fields here
    }

    void execute() {
        // Your method body as before comes here.
        // But you can extract methods easily.
    }
}

One additional note: You cannot reuse an instance of this class. I call them one-shot-objects that must be instantiated, used, and discarded.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.