0

I have code which looks like this:

if(XisNotY && DoStep1AndChangeXtoY()){
    if(AisNotB && DoStep2AndChangeAtoB(){
       if(IisNotJ && DoStep3AndChangeItoJ(){
          if(PIsNotQ && DoStep4AndChangePtoQ(){
          }
       }
    }
}

Now if Step3 fails, I want to fix external issues and re-run the process so that it can be taken to completion. This won't happen with the current implementation. I can take the first part of each condition out and do something like:

if(XisNotY && DoStep1AndChangeXtoY()){
}
if(XisNotY && AisNotB && DoStep2AndChangeAtoB()){
}
if(XisNotY && AisNotB && IIsNotJ && DoStep3AndChangeItoJ()){
}
if(XisNotY && AisNotB && IIsNotJ && PIsNotQ && DoStep4AndChangePtoQ()){
}

But it doesn't seem to be elegant. What is the best way to refactor this piece so that the conditions are re-runnable? Also, note that DoStep.. methods are not the same signature. They are all quite different method calls.

Edit: Clarification: This is part of a service endpoint code. Failure would mean throw exception and return. The re-run needs to happen in a new call to the same endpoint.

Noel
  • 83
  • 2
  • 2
  • 8
  • "Now if Step3 fails..." What exactly does failure look like? A thrown exception? Returning `false`? Both? – Spencer Bench Sep 01 '21 at 19:58
  • Does this code exist in a loop? Can you post more of the implementation? – John Sep 01 '21 at 19:59
  • Should have clarified. This is the code for a service endpoint. The failure would have thrown an exception. The idea is to fix issues and make the service call again. – Noel Sep 01 '21 at 20:02
  • `The re-run needs to happen in a new call to the same endpoint` - that does not seem to warrant change to this code, then, or? – 500 - Internal Server Error Sep 01 '21 at 20:09
  • With the above example, in the first service call, it successfully changes X to Y and A to B. In the second call because of that, it would never go inside the nested conditions and thus Step 3 and Step 4 wouldn't execute. I am trying to change the code so that the Step n and onwards can be re-run if Step n failed before. – Noel Sep 01 '21 at 20:13
  • Why must you keep checking `XisNotY` in the `if` logic for each subsequent "step"? If `XisNotY` was false, then X is Y, and you can skip `DoStep1...`. If `XisNotY` was true, but `DoStep1...` succeeded, then X is Y, and you can proceed. _Do you really need to keep checking `XisNotY` for all subsequent steps? Even if step 2 needs X to be Y, isn't it guaranteed to be so, since step 2 comes after step 1?_ – Sean Skelly Sep 01 '21 at 23:33

2 Answers2

0

You can create a state machine if your conditions getting to complicated (like this, or this).

Howto:

  • Create States for the if conditions
  • do the transitions - Switch States
  • Store state for rerun/resume
Kraego
  • 2,978
  • 2
  • 22
  • 34
0

If I understand your question and comments correctly, you should be able to do something like this:

private bool DoStep3AndChangeItoJ() {
    while (true) {
        try {
            ... // (Whatever was in this method before)
            return true;
        } catch (Exception e) {
            ... // (Fix the issue)
        }
    }
}
Spencer Bench
  • 647
  • 4
  • 7