Simplify huge if statements - design template?

I potentially have a set of if statements that look like this:

if (a and b and c and d) {
  // do stuff
} else (!a and b and c and d) {
  // do something else
} else (!a and !b and c and D) {
  // do yet something else
} ...

etc. for all possible permutations.

I thought about it:

switch ((a ? 'Y' : 'N') . (b ? 'Y' : 'N') . (c ? 'Y' : 'N') . (d ? 'Y' : 'N')) {

  case 'YNYN':
    // do stuff
    break;

  case 'NNNN':
    // etc.
    break;

}

is there a better way?

+5
source share
5 answers

What I will most likely do (without knowing the specifics) will build a series of classes for each state. Then click doStuff on this class:

class DoStuff { //The Client
    protected $strategies = array();
    public function addStrategy(iDoStuffStrategy $strategy) {
        $this->strategies[] = $strategy;
    }
    public function doStuff ($a, $b, $c, $d) {
        foreach ($this->strategies as $strategy) {
            if ($strategy->test($a, $b, $c, $d)) {
                return $strategy->doStuff();
            }
        }
        throw new RuntimeException('Unhandleable Situation!');
    }
}

interface iDoStuffStrategy {
    // Return a bool if you can handle this situation
    public function test($a, $b, $c, $d);
    // Execute the implementation
    public function doStuff();
}

Then each class will look like this:

public function StrategyFoo implements iDoStuffStrategy {
    public function test($a, $b, $c, $d) {
        return $a && $b && $c && $d;
    }
    public function doStuff() {
        //DoStuff!
    }
}
public function StrategyBar implements iDoStuffStrategy {
    public function test($a, $b, $c, $d) {
        return !$a && $b && $c && $d;
    }
    public function doStuff() {
        //DoStuff!
    }
}

This is mainly an implementation of a strategy template . The implementation of this method allows you to select a decision tree.

+7
source

, , . ifs....

0

case , , , .

, , n ^ 2 , if. , , ifs.

0

, .

, ? , , , . 16 (2 ^ 4), ? , , , if ifs.

if (b) {
  // cases where b is true
  if (...)
    ...
} else {
  // cases where b is false
  if (...)
    ...
}

switch, Y N .

0

I would treat your four logical elements as four bits, since the integer is from 0 to 15. I would create an array with 16 elements and store a pointer to a function in each element of the array. Every time you need to do this, I would evaluate the boolean values ​​in the bitmap, convert to int and call the method stored in this array index.

I know what you're asking about PHP, which I'm afraid I don't know. In C #, you can do something like this:

static class Multiplexer
{
    public static string Multiplex(bool a, bool b, bool c, bool d)
    {
        var i = 0;
        i |= (a ? 1 : 0) << 3;
        i |= (b ? 1 : 0) << 2;
        i |= (c ? 1 : 0) << 1;
        i |= (d ? 1 : 0);
        return _functions[i]();
    }

    private static Func<string>[] _functions = new Func<string>[] {
        () => { return "pie";},
        () => { return "index 1"; },
        () => { return DateTime.Now.ToString(); },
        () => { return "pie";},
        () => { return "index 1"; },
        () => { return DateTime.Now.ToString(); },
        () => { return Assembly.GetExecutingAssembly().FullName; },
        () => { return ""; },
        () => { return "pie";},
        () => { return "index 1"; },
        () => { return DateTime.Now.ToString(); },
        () => { return "pie";},
        () => { return "index 1"; },
        () => { return DateTime.Now.ToString(); },
        () => { return Assembly.GetExecutingAssembly().FullName; },
        () => { return ""; }};
}
0
source

All Articles