将我的表单重构为面向对象的最佳方法是什么?

4
(注意:这与这个问题有关,但我认为它可以写得更清楚,所以我再试一次——我的更新只有有限的帮助。)
我继承了一些代码,创建了一个复杂的表单,包含许多部分和许多可能的视图,取决于许多参数。我已经在使用它一段时间了,并最终有机会考虑进行一些重构。它目前是以过程方式编写的,具有一堆看起来像这样的函数:
get_section_A ($type='foo', $mode='bar', $read_only=false, $values=array()) {
    if ($this->type == 'foo') { 
        if ($this->mode == 'bar') { }
        else { }
    } else { }
}

传递这些参数很麻烦,所以我开始编写一个像这样的类:
class MyForm {
    public $type;          // or maybe they'd be private or 
    public $mode;          // I'd use getters and setters 
    public $read_only;     // let's not get distracted by that :)
    public $values;
    // etc.

    function __constructor ($type='foo', $mode='bar', $read_only=false, $values_array=array()) {
        $this->type = $type;
        // etc.
    }

    function get_sections () {
        $result = $this->get_section_A();
        $result .= $this->get_section_B();
        $result .= $this->get_section_C();        
    }      

    function get_section_A() { 
        if ($this->type == 'foo') { }
        else { }
    }
    function get_section_B() {}
    function get_section_C() {}
    // etc.
}

问题在于过程函数被分成了几个文件(针对一些部分),如果我将它们全部合并到一个单独的类文件中,那么我会得到 2500 行代码,这感觉不太好处理。我想过几种解决方案:
  1. 忍受难看的参数,把时间用在其他事情上 :)
  2. 忍受有 2500 行的文件
  3. 为每个部分组创建一个单独的类,以某种方式“知道”这些参数的值
如果我选择第三种方法,我想到了两种基本方法:
  1. 将 MyForm 对象作为单个参数传入
  2. 创建一个 FormSectionGroup 类,并设置静态属性,然后在组文件中,每个类都将扩展 FormSectionGroup 并自动访问这些参数的当前值。
1)可能更容易设置,一旦我进入 get_section_A(),无论我是说 $this->type 还是 $myForm->type 都没有太大区别,但它并不完全是面向对象的。(实际上,我可以在不真正转换为面向对象的方法下这样做。)
还有其他方法吗?哪种方法更好?
4个回答

1
我很想写一个详细的解释来说明如何做到这一点,但我有点懒。不过,我还是有足够的精力来指向Zend框架中的Zend_Form。可能需要一些依赖项才能使其正常工作(Zend_View、Elements、Decorators),但一旦你拥有了它们,它就可以非常优雅地处理那种类型的情况。

强烈推荐Zend表单实现。当我与几位开发人员一起工作时,他们第一次学习如何通过Zend_Form进行表单布局和验证,这是他们职业生涯中的关键时刻。 - JC.

0
我在回答你之前就想到了这个 - 这个问题非常适合 装饰器模式
不过这将是一项不小的任务。但我认为,一旦完成,你会有一种惊人的满足感/成就感。

0

最近我做了很多Cocoa编程,因此我倾向于用MVC(Model-View-Controller)模式来看待事物。因此,我将把表单视为其各个部分的控制器。

每个部分对象应负责跟踪其状态、值以及是否应该显示。或者更准确地说,section_model应负责处理值(默认值、验证等),section_view应负责显示(或不显示)部分内容,而section_controller则应跟踪部分的状态并向表单对象报告结果。

表单对象应实例化部分控制器,告诉它们显示或隐藏等操作,并获取状态报告。表单对象真正扮演一个控制器的角色,可以决定何时表单已完全填写。您可以拥有一个form_model对象来保存收集到的数据,或者也可以让section_model对象的一部分参与其中。需要一段时间才能感受到不同对象之间的互动方式,但是我知道如果您在设计您的对象时遵循纪律(关键是:什么是对象的责任,什么不是),您将获得更好的概述,并且您的代码将更容易升级。一旦您发现改进自然而然地出现,那么您就走在了正确的道路上。


0
如果你有时间去做第三个选项,长期来看你可能会最开心。就我个人而言,在我的工作中,我没有太多时间进行如此彻底的重构,所以我可能会被迫选择第一个选项。对我来说,第二个选项听起来像是两个世界中最糟糕的结合。要付出很多努力去得到你不喜欢的代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接