2012-04-06 52 views
2

在一个类中,我有一个处理方法,它根据什么post/get变量可用来执行操作。下面是一个简单的例子:

public function handleAll(array $vars) { 
    if (isset($vars['var1'])) { 
     $this->doThisAction($vars['var1']); 
    } else if (isset($vars['var2'])) { 
     $this->doAnotherAction($vars['var2']); 
    } 
} 

所以在运行时的方法可以这样调用$handler->handleAll($_POST)。 问题是存储在$ vars数组中的变量必须命名为“var1”&“var2”等。这意味着处理代码与html表单元素的名称相结合或者在url中获取变量(或者实际上键任何数组传入)。

允许注入任何变量的数组使得该方法具有灵活性,这是必要的,因为它也是多态的。类继承此方法并用它来调用它自己的操作。这样做的结果是,外部处理方法所需的功能并不明显。这意味着必须检查实现,找出它的功能(除非我将代码复制到phpdoc中,这很愚蠢)。

我不知道如何解决这个问题。索引页面(来自多个这样的类)暴露出巨大的if/case语句会导致非常混乱的代码,因此最好将所有这些封装在方法中。此外,将它作为负责调用操纵它自己状态的行为的类的一种方法是有意义的(责任驱动设计)。我想过把每个变量作为方法的一个参数,但是对于某些类来说,参数列表会非常大。同样,这意味着不同类的handleAll()方法不能自动调用,因为每次调用都需要显式注入所有参数,从而消除多态性方面。

总结我需要保持多态的方法,但我需要某种方式从HTML表单或网址的用户输入解耦处理代码。这样做也许有一种将接口与实现分开的方法。我很惊讶,我无法找到任何解决方案,这似乎是一个普遍的问题。

+0

而不是'handleAll'处理所有事情,为什么你没有单独的方法处理他们期望的特定后期数据变量? – 2012-04-06 19:53:38

+0

如果我要为每个方法提供post变量,那么我会在任何地方都获得大量的if/else代码。此外,多态性将被删除,这意味着每个类都需要显式调用每个类,这意味着许多对handleAll()的调用无法在循环中进行。如果我想使每种方法都能与特定的后置变量一起工作,所以不能注入依赖关系,那么耦合问题依然存在。 – Jonathan 2012-04-06 20:08:08

+0

你不能使用很多MVC框架之一吗?他们默认提供你想要的。基本上你需要在应用程序中“分割”控制器,每个控制器都有自己的责任。国际海事组织目前的方法是多形态的。它更像是一个前端控制器。 – MikeSW 2012-04-06 20:55:14

回答

1

我不确定您所描述的内容是否可以避免。

如果您的代码需要特定的参数(无论是包含某些值还是其他任何值的数组),该函数将始终取决于正确填充的参数。

如果我有function foo($a, $b, $c),我将始终填写参数。如果他们来自POST,那么我需要从POST中取出它们。即使该功能采用array('a' => ..., 'b' => ..., 'c' => ...)代替,也是如此。然而,如果你想从表单中解耦你的表单,你可以使用一个简单的函数将POST数组转换成你的处理函数所期望的格式。尽管如此,我并没有看到任何理由,因为如果您不需要,为什么会增加额外的复杂性?

如果您希望更好地定义您的处理程序需要什么类型的数组,您可以考虑让它需要一个对象。这种方法有时被称为parameter object

使用参数对象的好处在于,您可以在构造函数中轻松设置所需的参数,并使用setter作为可选参数。任何使用你的代码的人都可以看看你的对象的接口,看看需要什么值。

如果您的处理程序使用的值实际上是相互关联的,我会考虑创建一个实际的业务逻辑类型对象。使用来自POST的数据创建它,并将处理值的代码移动到对象中的方法中。

+0

这是一个很好的答案和一个很好的解决方案。唯一的问题是你的建议基本上是目前班级的责任。它是一个控制器,它接收/获取被验证的信息并将其转换为模型的对象(例如数据库表的CRUD)。我将验证封装在控制器中,以便它可以输出关于它正在发送的信息的反馈(例如,视图输出特定于该问题的无效输入消息)。如果我将所有这些验证移至业务逻辑对象,那么您认为保留该功能的最佳方式是什么? – Jonathan 2012-04-07 01:08:05

+1

是的,一个控制器将是与POST等耦合的部分,所以这是正确的。至于验证,如果你只需要它在控制器中,你可以保留它。如果你决定把它移动到其他地方,你可以考虑制作一个验证对象的方法,并且可能会返回一个包含错误(如果有的话)的数组或者沿着这些行的东西。 – 2012-04-07 01:23:29

+0

我已经有业务逻辑对象,所以我会给他们另一个构造函数(静态方法,返回自我的一个实例),在其中注入一个数组($ _POST/$ _ GET/whatever),其他参数可以是数组键。例如'fromArr($ _ POST, '标题', '体')'。你可以在界面中定义一个方法,使用不同数量的参数吗?在Java中,我通常会超载。我想我会重新定义handleAll作为'route($ action,Item $ item)',但是继承路由的子类不能定义'route($ action,SpecificItem $ item)'。在Java中我会使用泛型'Controller '。 – Jonathan 2012-04-07 11:45:19

0

解耦和自动化处理方法,也可能是缩小范围的痛苦方法。但是没有太多的选择,除了为事物创建处理程序之外。不过,我想添加一些东西。允许默认值和支持变体

function handlePOST() { } 
function handleGET() { } 
function handleArr() { } 

现在,这些函数可以代表它们代替函数的变体。

但是,它们并不是编写所有处理程序的更好方法。但是开关会缩短它们,并使用单独的功能进行处理。

switch($_POST['var1']) { 
    case "value1": callPostValue1(); break; 
    default: callPostDefaultHandler(); break; 
}