我可能有一组看起来像这样的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
} ...
等所有可能的排列。
我想到了这样做:switch ((a ? 'Y' : 'N') . (b ? 'Y' : 'N') . (c ? 'Y' : 'N') . (d ? 'Y' : 'N')) {
case 'YNYN':
// do stuff
break;
case 'NNNN':
// etc.
break;
}
有更好的方法吗?
答案 0 :(得分: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();
}
然后,每个班级看起来像这样:
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!
}
}
它基本上是Strategy Pattern的实现。这样做可以让你分离出决策树。
答案 1 :(得分:0)
我认为您应该考虑使用决策树解决此问题,其中不同的节点可能是最终状态。 然后你可以在树上组合你的问题,并摆脱所有这些ifs ....
答案 2 :(得分:0)
当我需要根据一组条件汇总数据时,我对您的案例陈述采取了类似的方法,其中有五个开关可以打开或关闭。
为了处理有关可能情况的聚合信息,这工作正常,但在该用例之外,如果确实存在n ^ 2个不同的操作,那么我将坚持使用多个if语句。如果没有那么多排列,我会将相似的结果组合在一起以减少ifs的数量。
答案 3 :(得分:0)
是的,还有更好的方法。
哦,你想要更多细节吗?好吧,你似乎有一些带有四个变量的真值表。是否有16种可能的结果(2 ^ 4),或者您只对一个子集感兴趣?如果有一个变量具有大致相同数量的结果,可以使用它作为最顶层的if语句,并使用嵌套的ifs。
if (b) {
// cases where b is true
if (...)
...
} else {
// cases where b is false
if (...)
...
}
您也可以使用switch语句,而不是由Y和N组成的字符串使用位域。
答案 4 :(得分:0)
我会将你的四个布尔值视为四位,因此是0到15之间的整数。我将创建一个包含16个元素的数组,并在数组的每个元素中存储一个函数指针。每次你需要这样做时,我都会将布尔值计算成一个位模式,转换为int,然后调用存储在数组索引中的方法。
我知道你在问PHP,我恐怕不知道。在C#中,你可以这样做:
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 ""; }};
}