MVC:如何减少多态方法的数量?

时间:2012-03-10 00:15:21

标签: java php model-view-controller oop polymorphism

我正在研究PHP中的MVC框架,但我主要使用java,我正在寻找一个解决这个问题的解决方案,它遵循OOP原则并可以转换为其他语言。

我有一个模型抽象类,它与一些数据(数据库,xml,无论如何)交互。继承类必须实现这些方法:

abstract class Model {

abstract public function nextItem();

abstract public function insert(Map $item);

abstract public function update(Map $item);

abstract public function delete(Map $item);

abstract public function exists(Map $item);

abstract public function countItems();

abstract public function allItems();

控制器传递一个Map对象,该对象保存有关要插入,更新,删除等项目的信息。这意味着模型和控制器是分离的,任何Model都可以注入控制器,前提是有一个实现这些方法。

在实践中使用此类时,我发现有些情况下控制器所需的操作非常独特,例如以特定方式重新排序数据。这是一个不好的解决方案:

abstract public function reorder(Map $item);

此解决方案意味着每个模型都必须实现此方法,这是不必要的。同样想象一下,如果我需要其他方法,抽象方法的数量会增长和增长,每个方法都需要实现。

另一种解决方案是:

abstract public function action(Map $item, $action)

$ action变量将是一个定义动作的字符串。所以你可以实现不同的方法,但只能用多态action()方法调用它们:

if ($action === "reorder") { $this->reorder($item); }

此解决方案的唯一问题是方法签名中的正确命令不明显。例如,$ action字符串可以是任何东西,另一个开发人员必须检查方法体(实现)以找到可接受的字符串。简单地在文档中说明它们似乎是一个脆弱的解决方案。如果将模型注入到未实现所有必需操作的控制器中,该怎么办?抛出异常?

似乎我必须错过某种非常明显的解决方案,我不想继续执行上面的那个,然后在我找到更好的解决方案时必须重新进行重构。有什么想法吗?

修改 到目前为止,使用多个接口似乎是最好的解决方案。但是存在类型安全问题。如果我要将一个实现接口ReOrderable的Model注入我的Controller类中,我希望能够做__construct(实现这些接口$ model的任何模型)。我可以创建更多抽象类,如ReOrderableModel,然后执行__construct(ReOrderableModel $ model),但可能有任意数量的接口组合,我必须为每个接口组合一个额外的抽象类。我还可以将Model转换为接口并使用多个接口继承,但实际上会出现同样的问题。我一定错过了什么。

3 个答案:

答案 0 :(得分:1)

我将定义一个IReOrderable接口,并让您的实际Model类实现此接口。如果它不适用于所有继承类,则不需要在抽象类级别完成。

我使用了一个abstract Model类,然后使用了大量的Interfaces来实现Model个实现。

答案 1 :(得分:1)

一个选项(不确定在您的上下文中是否有意义)是模仿Java Collections。某些操作将抛出UnsupportedOperationException。麻烦的是,来电者很少知道什么时候到那里。

如果您使用第二个解决方案,第二个参数指示要采取的操作,我强烈建议使用枚举。 (php有一个等价的吗?)让另一个程序员更容易找出可能性,它绝对避免了许多错误。

答案 2 :(得分:0)

一方面,抽象类中的所有方法都不需要是抽象的。因此,可以选择创建高度专业化方法的具体版本,并让子类根据需要覆盖这些方法。根据您的需要,也许不那么吸引人,您也可以使用其他界面来补充抽象类。所述接口将由需要的子类实现。

为了说明上述内容,您可以

 public void function reorder(Map $item){
     //this is a concrete function that does nothing
 }

因为该函数不是抽象的,所以它不必被子项覆盖。