(Note: this is related to this question, but I think it could have been written more clearly, so I'm trying again -- my update only helped to a limited extent.)
(注意:这与这个问题有关,但我认为它可以写得更清楚,所以我再试一次 - 我的更新只在一定程度上有所帮助。)
I've inherited some code that creates a complex form with numerous sections, and lots of possible views, depending on a number of parameters. I've been working with it for a while, and finally have a chance to think about doing some re-factoring. It's currently written procedurally, with a bunch of functions that look like this:
我继承了一些代码,这些代码创建了一个包含许多部分的复杂表单,以及许多可能的视图,具体取决于许多参数。我已经和它一起工作了一段时间,最后有机会考虑做一些重新分解。它目前是在程序上编写的,有一堆看起来像这样的函数:
get_section_A ($type='foo', $mode='bar', $read_only=false, $values=array()) {
if ($this->type == 'foo') {
if ($this->mode == 'bar') { }
else { }
} else { }
}
Passing around those parameters is nasty, so I've started writing a class like this:
绕过这些参数是很讨厌的,所以我开始写一个这样的类:
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.
}
The problem is that the procedural functions are split into a few files (for groups of sections), and if I combine them all into a single class file, I'm looking at 2500 lines, which feels unwieldy. I've thought of a few solutions:
问题是程序功能被分成几个文件(对于组的部分),如果我将它们全部组合成一个类文件,我会看2500行,这感觉很笨拙。我想到了一些解决方案:
- keep living with the nasty parameters and do something else with my time :)
- live with having a 2500 line file
- create a separate class for each group of sections that somehow "knows" the values of those parameters
继续生活在讨厌的参数,并用我的时间做其他事情:)
拥有2500行文件
为每组部分创建一个单独的类,以某种方式“知道”这些参数的值
If I do #3, I've thought of two basic approaches:
如果我做#3,我想到了两个基本方法:
- pass the MyForm object in as a single parameter
- create a FormSectionGroup class with static properties that get set in MyForm, then in the group files, each class would extend FormSectionGroup and automatically have access to the current values for those parameters.
将MyForm对象作为单个参数传递
创建一个FormSectionGroup类,其中包含在MyForm中设置的静态属性,然后在组文件中,每个类都将扩展FormSectionGroup并自动访问这些参数的当前值。
1) is probably easier to set-up, and once I'm inside get_section_A()
whether I say $this->type
or $myForm->type
isn't all that different, but it's not exactly OOP. (In fact, I could do that without really changing to an OOP approach.)
1)可能更容易设置,一旦我在里面get_section_A()我是否说$ this-> type或$ myForm-> type并不是那么不同,但它并不完全是OOP。 (事实上,我可以在不改变OOP方法的情况下做到这一点。)
Are there other approaches? Thoughts about which is better?
还有其他方法吗?关于哪个更好的想法?
4 个解决方案
#1
1
I would love nothing more than to write a lengthy explanation of how to do this, but I'm feeling a bit lazy. I do however have enough energy to point you instead to Zend_Form from the zend framework. There may be some dependencies to make it work properly (Zend_View, Elements, Decorators), but once you have them, it handles that type of situations quite gracefully.
我只想写一个如何做到这一点的冗长解释,但我感觉有点懒。然而,我确实有足够的精力指向Zend_Form来自zend框架。可能有一些依赖项使它正常工作(Zend_View,Elements,Decorators),但是一旦你拥有它们,它就会非常优雅地处理这种情况。
#2
0
I thought of this when I posted in your previous question - this problem reeks of decorator pattern.
当我在上一个问题中发布时,我想到了这个问题 - 这个问题充满了装饰模式。
It's going to be no small task, though. But I think you'll have an amazing sense of satisfaction/accomplishment once you get it done.
不过,这将是一项不小的任务。但是,一旦你完成它,我认为你会有一种惊人的满足感/成就感。
#3
0
Having done a lot of Cocoa programming recently, I tend to view things in MVC-pattern (Model-View-Controller) terms. Hence, I'd look at the form as a controller of its various sections.
最近做了很多Cocoa编程,我倾向于用MVC模式(模型 - 视图 - 控制器)术语来查看。因此,我将该表格视为其各个部分的控制者。
Each section object should be responsible for keeping track of its status, values and whether or not it should be displayed. Or to be precise, the section_model would take care of the values (default values, validation, etc), the section_view would take care of displaying (or not) parts of the section and the section_controller would send keep track of the status of the section and report results to the form object.
每个部分对象应负责跟踪其状态,值以及是否应显示它。或者确切地说,section_model将处理值(默认值,验证等),section_view将负责显示(或不显示)部分的部分,section_controller将发送跟踪部分的状态并将结果报告给表单对象。
The form object should instantiate the section controllers, tell them to display or hide or whatever, and get status reports. The form object, really act a controller, can then decide when the form if completely filled out. You may have a form_model object to save the collected data, or maybe you'd rather have the section_model objects take part of that. It will take a while to get a feeling for how the different objects interact but I know from experience that if you are disciplined in designing your objects (the key is: what is an object's responsibility and what is not), you will gain a better overview and your code will be easier to upgrade. Once you find that improvements start to arise naturally, you are on the right track.
表单对象应该实例化段控制器,告诉它们显示或隐藏或者其他什么,并获取状态报告。表单对象,实际上是一个控制器,然后可以决定何时完全填写表单。您可能有一个form_model对象来保存收集的数据,或者您可能希望section_model对象参与其中。需要一段时间才能感受到不同对象的交互方式,但我从经验中知道,如果你在设计对象时有纪律(关键是:什么是对象的责任,什么不是),你会获得更好的概述和您的代码将更容易升级。一旦你发现改进开始自然而然,你就走在了正确的轨道上。
#4
0
If you have the time to work on doing #3, you will probably be the happiest over the long run. Personally, I don't have the time in my job to refactor to that degree very often, and so I'd probably be forced to pick #1. #2 sounds like the worst of both worlds to me. Lots of work to get code you don't like.
如果你有时间做#3,从长远来看,你可能会是最开心的。就个人而言,我没有时间在工作中经常重构那个学位,所以我可能会*选择#1。 #2听起来像是对我来说两个世界中最糟糕的。很多工作来获取你不喜欢的代码。
#1
1
I would love nothing more than to write a lengthy explanation of how to do this, but I'm feeling a bit lazy. I do however have enough energy to point you instead to Zend_Form from the zend framework. There may be some dependencies to make it work properly (Zend_View, Elements, Decorators), but once you have them, it handles that type of situations quite gracefully.
我只想写一个如何做到这一点的冗长解释,但我感觉有点懒。然而,我确实有足够的精力指向Zend_Form来自zend框架。可能有一些依赖项使它正常工作(Zend_View,Elements,Decorators),但是一旦你拥有它们,它就会非常优雅地处理这种情况。
#2
0
I thought of this when I posted in your previous question - this problem reeks of decorator pattern.
当我在上一个问题中发布时,我想到了这个问题 - 这个问题充满了装饰模式。
It's going to be no small task, though. But I think you'll have an amazing sense of satisfaction/accomplishment once you get it done.
不过,这将是一项不小的任务。但是,一旦你完成它,我认为你会有一种惊人的满足感/成就感。
#3
0
Having done a lot of Cocoa programming recently, I tend to view things in MVC-pattern (Model-View-Controller) terms. Hence, I'd look at the form as a controller of its various sections.
最近做了很多Cocoa编程,我倾向于用MVC模式(模型 - 视图 - 控制器)术语来查看。因此,我将该表格视为其各个部分的控制者。
Each section object should be responsible for keeping track of its status, values and whether or not it should be displayed. Or to be precise, the section_model would take care of the values (default values, validation, etc), the section_view would take care of displaying (or not) parts of the section and the section_controller would send keep track of the status of the section and report results to the form object.
每个部分对象应负责跟踪其状态,值以及是否应显示它。或者确切地说,section_model将处理值(默认值,验证等),section_view将负责显示(或不显示)部分的部分,section_controller将发送跟踪部分的状态并将结果报告给表单对象。
The form object should instantiate the section controllers, tell them to display or hide or whatever, and get status reports. The form object, really act a controller, can then decide when the form if completely filled out. You may have a form_model object to save the collected data, or maybe you'd rather have the section_model objects take part of that. It will take a while to get a feeling for how the different objects interact but I know from experience that if you are disciplined in designing your objects (the key is: what is an object's responsibility and what is not), you will gain a better overview and your code will be easier to upgrade. Once you find that improvements start to arise naturally, you are on the right track.
表单对象应该实例化段控制器,告诉它们显示或隐藏或者其他什么,并获取状态报告。表单对象,实际上是一个控制器,然后可以决定何时完全填写表单。您可能有一个form_model对象来保存收集的数据,或者您可能希望section_model对象参与其中。需要一段时间才能感受到不同对象的交互方式,但我从经验中知道,如果你在设计对象时有纪律(关键是:什么是对象的责任,什么不是),你会获得更好的概述和您的代码将更容易升级。一旦你发现改进开始自然而然,你就走在了正确的轨道上。
#4
0
If you have the time to work on doing #3, you will probably be the happiest over the long run. Personally, I don't have the time in my job to refactor to that degree very often, and so I'd probably be forced to pick #1. #2 sounds like the worst of both worlds to me. Lots of work to get code you don't like.
如果你有时间做#3,从长远来看,你可能会是最开心的。就个人而言,我没有时间在工作中经常重构那个学位,所以我可能会*选择#1。 #2听起来像是对我来说两个世界中最糟糕的。很多工作来获取你不喜欢的代码。