如何避免大转换语句?

时间:2010-08-08 05:39:34

标签: php design-patterns

我有一个内部应用程序,其中一个函数包含太多的switch case。

这是在php中开发的。此特定功能用于将更改写入数据库,并保留单个字段值的历史记录。所以它的作用是每个领域都有一个案例,因为不同的领域需要应用不同的东西。

switch ($item){  
    case 'item1':  
        do_something();  
    case 'item2':  
        do_something_different():  
}

在这种情况下是否存在设计模式。每个项目的功能看起来都不是未来的证据。

更新pastebin link

4 个答案:

答案 0 :(得分:9)

这不是一个好的功能。它应该是三个函数,edit_nameedit_manageredit_liscencedata。您可以将案例之间重复的所有内容移动到您应该定义的Change类的构造函数中。

答案 1 :(得分:3)

您并没有真正透露该示例的代码,但另一种选择是使用状态机。您可以获取数组并将项目名称指定为键,值将是函数。

$machine = array('item1' => do_something, 'item_2' => do_something_different);
$machine['item1']();

然后它甚至可以打开可插拔性,你可以在其中包含一个文件:

$machine['item3'] = do_something_else_else;

答案 2 :(得分:1)

从提供的代码片段来看,显然你面临着相当严重的混合责任和复制粘贴编码的情况,因为缺乏因子分解。您的编辑功能处理至少三个不同层和三个不同对象的内容。我可能应用的重构操作是为您正在处理的每个不同数据集提取Validator类,同样用于在每种情况下与数据库交互的Model类和用于将三者绑定在一起的命令:接受数据,传递它通过验证器,然后与各自的模型进行交互以保留数据。然后,模型将根据成功的操作生成变更条目。

如果你现在不愿意接受如此重大的改变,那么良好的第一步就是将编辑功能中的不同部分分成其他更好的分区函数,并且只有在你首先解决这个问题时才会担心类和多态。栏。为了更好地理解为什么你的代码被破坏以及你可以做些什么来修补它,我建议你阅读像Refactoring(Martin Fowler)或者像实用程序员这样的东西。

答案 3 :(得分:0)

只是一个想法,但你可能想要一个可用的钩子系统而不是switch语句......

所以,对于像

这样的可能的东西的列表
item1, item2, ..., itemN

你可能会尝试像

这样的东西
function item1action ( ) { /* ... */ }
function item2action ( ) { /* ... */ }
function itemNaction ( ) { /* ... */ }

并有某种默认方法,如

function itemDefaultAction ( ) { /* ... */ }

因此,对于之前的switch语句,您可以改为

$function = "{$item}action";
if (! function_exists($function)) {
    return itemDefaultAction();
}
call_user_func($function);
return call_user_func($function)