2

I normally adopt the Enum argument suggested in Are booleans as method arguments unacceptable? and implement it using the strategy pattern.

However, I now have a complicated logic that I cannot move into an Enum due to the fact that there's no non-static Enum and a ridiculous amount of variables that needs to be copied into and out of the method in the Enum. If I use a switch in the code instead of the strategy pattern, I seem to lose all the benefits apart from simple clarity.

For this particular method, there can only be two possibilities, so would a boolean argument be more acceptable? (If a enum is used, I am required by our coding standard to handle any unknown enums which seems unnecessary in this case.) Maybe I can put the boolean into constants and call the method using the constants?

Edit:

The complicated logic is proprietary code, but it is something like

public void method(A a, B b, boolean replaceMe) {
    // Create and prepare local variables c, d, e, f, g;
    if (replaceMe) {
        // doSomethingWith a, b, c, d, e and return e, f, g
    } else {
       // doSomethingElseWith a, b, c, d, e and return e, f, g
    }
    // Process e, f, g further
}
Community
  • 1
  • 1
billc.cn
  • 7,187
  • 3
  • 39
  • 79
  • 1
    What if you showed some of that "complicated logic" and the context in which it is applied? – fge Jul 03 '13 at 11:16
  • Hmmm you could replace this if with a strategy and wrap the parameters a..g in a container. Map if they are all the same type or an on parameter class – Marco Forberg Jul 03 '13 at 11:23
  • Can't you write two methods: `methodNoReplace` and `methodWithReplace` or something like that, and delegate the common portion, if any, to a private helper method? – assylias Jul 03 '13 at 11:28

1 Answers1

2

You could use the strategy pattern once more

public interface DoSomethingWithA2GStrategy { // horrible name I know ;)
    void doSomething(A2GParameterContainer params);
}

and for the container you create something like this:

public class A2GParameterContainer {
    TypeOfA a;
    // ...
    TypeOfG g;

    //getters and setters
}

and then modify your method a bit and pass in the concrete strategy

public void method(A a, B b, DoSomethingWithA2GStrategy strategy) {
    // Create and prepare local variables c, d, e, f, g;
    A2GParameterContainer params = new A2GParameterContainer();
    params.setA(a);
    // ...
    params.setG(g);

    strategy.doSomething(params);
    // take e, f, g from the container
    // Process e, f, g further
}
Marco Forberg
  • 2,634
  • 5
  • 22
  • 33
  • This is the design I am trying to avoid though. This design makes the caller clearer to read, but dramatically complicates the callee method (i.e. I now have two additional classes and at least 20 lines of boilerplate). I think I'll look into the e, f, g arguments and see if they can be re-derived from a single one in the "Process e, f, g further" bit. – billc.cn Jul 03 '13 at 11:56
  • well i welcome tiny classes with a sharply defined functionality if it helps we clean up long methods. Sorry, since you are not allowed to show more of the complicated logic, we can't be of much help. Maybe this should be migrated to http://codereview.stackexchange.com – Marco Forberg Jul 03 '13 at 12:00
  • @billc.cn what datatypes do you have for your variables? maybe you can just pass e, f and g as modifiable types – Marco Forberg Jul 03 '13 at 13:45
  • @MarcoForberg `f` and `g` are generated by the strategy code though, so some kind of holder would still be required to pass them out. I eventually implemented this with a boolean argument and two constants to make the meaning of true and false clear. None of my colleagues had any problems with it in code reviews. Also, I didn't even know codereview.stackexchange.com existed. Thank you for pointing it to me. I'll post questions like this there next time. – billc.cn Jul 03 '13 at 16:23
  • I generally dislike bag-type objects. Also I dislike output-parameters. Is there a drawback to using instance variables on the strategy object and having the getters and setters there instead? Then you can also take away the getters for the input variables and the setters for the output variables. – Erik Madsen Jul 04 '13 at 08:12
  • 1
    @ErikMadsen the only drawback i could imagine when using stateful straegies is that you can't build them as singletons – Marco Forberg Jul 04 '13 at 09:01