简化巨大的if语句 - 设计模式?

lon*_*eck 5 php

我可能有一组看起来像这样的if语句:

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
} ...
Run Code Online (Sandbox Code Playgroud)

等等所有可能的排列.

我想这样做:

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

  case 'YNYN':
    // do stuff
    break;

  case 'NNNN':
    // etc.
    break;

}
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?

irc*_*ell 8

我可能会做的(不知道具体细节)是为每个州建立一系列的课程.然后将doStuff推送到该类:

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();
}
Run Code Online (Sandbox Code Playgroud)

然后,每个类看起来像这样:

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!
    }
}
Run Code Online (Sandbox Code Playgroud)

它基本上是战略模式的一个实现.这样做可以让你分离出决策树.


np-*_*ard 0

我认为你应该考虑用决策树来解决这个问题,其中不同的节点是可能的最终状态。那么你可以将你的问题写在一棵树中,并摆脱所有这些如果......