Closed. This question needs to be more
focused。它当前不接受答案。
想改善这个问题吗?更新问题,使其仅通过
editing this post专注于一个问题。
3年前关闭。
Improve this question
注意:
该问题已更新,以提供比以前更多的细节和见识。
更新:
我只想对回复的每个人表示感谢。对于哪种设计模式最适合Widget,我仍然很茫然。也许是Factory模式或Builder模式之一?
我刚刚开始一个新项目,需要使用MVC,OO和设计模式。
这就是想法:想象一个显示一组小部件的页面。这些小部件(通常)是基于数据库中几个单独表中包含的数据的图表。我使用一个运行中的页面示例来报告学生的表现。
高等级要求
显示一组(仅HTML)窗口小部件的页面。
小部件的数据将基于数据库查询。
该页面可用于查看包含类似布局数据的单独数据集。例如,一个页面将显示小部件,这些小部件报告单个学生表现的各个方面。
想要查看另一个学生的表现,请拉起另一页。不需要为不同的学生显示不同的窗口小部件(尽管以后可能会很好)。
可能有很多学生,但是数据库中包含的数据对所有学生的布局都是相似的。
窗口小部件的显示方式可以轻松更改(例如,将窗口小部件从显示为饼形图更改为条形图)。
小部件应该能够快速创建。
低级别要求
当前数据不会更改,因此小部件将不需要自动更新。
小部件可以表示两种事物的比率(例如,以饼图形式表示失败测试与成功测试的比率),一系列点或有时是单个数值。
新窗口小部件的开发应轻而易举,无需修改现有代码。
使用的框架:Zend Framework,基于MVC。
(至少)有三件事定义了一个小部件:要报告的数据集(在上面的示例中,是学生ID),描述了要报告的指标的查询以及渲染模式(barchart,时间序列等)。
这是分解MVC每一层职责的通行证:
视图:Zend视图是注入了PHP的HTML模板。它们将包含几种类型的小部件之一。小部件具有多种形式,包括:静态JPEG图像(从远程站点加载,即
<img src="http://widgetssite.com?x=2&y=3"/>
,基于JSON的javascript小部件或各种图表(piechart,条形图等)。
控制器:创建小部件,然后将它们分配给视图。要在页面上显示的一组小部件需要保留在某处。由于我在该视图中没有想到执行此操作的好方法,因此现在将其添加到控制器职责中。如果有更好的地方,请大喊。控制器还必须处理任何其他输入参数,并将它们传递给小部件。例如,data_set ID可以在URL行作为
http:/.../report/?student_id=42
传递
模型:Zend Framework中的模型负责提取数据,因此很可能会为每个用于访问数据库的小部件包含一个类。
一些要点:
此处的模型表示特定小部件的数据。因此,必然需要知道查询的内容,以便将获取该数据所需的表汇总在一起。
在小部件可以呈现数据之前,最有可能需要执行一个附加的处理步骤。这取决于将使用哪个渲染器。有时可能需要根据返回的数据形成一个url。其他时间,一个JSON数组。其他时候可能会创建一些标记。这可以在模型,控制器或视图中进行。除非有人能想到将其移至控制器或视图的充分理由,否则最好将其保留在模型中并使视图和控制器变薄。
同样,小部件将由三部分组成,即参数,数据和渲染器。
问题的很大一部分是:在面向对象设计中代表小部件的一种好方法是什么?我已经问过一次,无法得到答案。是否有可应用于该项目最有意义的设计模式?
这是Widget的一个非常简单的类的第一步:
class Widget{
//method called by the view
render() {//output the markup based on the widget Type and interleaved the processed data}
//methods called by the controller:
public function __construct() {//recieve arguments for widget type (query and renderer), call create()}
public function create() {//tell the widget to build the query, execute it, and filter the data}
public function process_data() {//transform into JSON, an html entity etc}
//methods called by the model:
public function build_query() {...};
public function execute_query() {...};
public function filter_data() {...};
}
看着它,我已经看到一些问题。
例如,将在控制器中创建的窗口小部件传递到视图以进行渲染很简单。
但是,在实施模型时,似乎并不那么直接。表网关模式比ORM更易于实现。但是由于表网关模式对每个模型/表都有一个类,因此似乎不合适。我可以为特定的表创建一个模型,然后在其中实例化任何其他需要的模型。但这似乎不适合表网关模式,而是适合ORM模式。可以用多个表实现表网关模式吗?有哪些替代方案?控制器创建窗口小部件并且窗口小部件创建模型是否有意义?
出现的另一个问题是,这种设计无法轻松创建小部件。即。假设我想创建一个PiechartWidget,可以重用多少代码?使用一些面向对象的想法(例如接口或抽象类/方法和继承)是否更有意义?
假设我抽象了Widget类,因此仅具体定义了共享方法,而其余的则声明为抽象方法。修改Widget类使其抽象(第二遍):
abstract class Widget{
private $_type;
private $_renderer;
//methods called by the controller:
//receive arguments for widget type (query and renderer),
protected function __construct($type, $renderer) {
$this->_type = $type;
$this->_render = $renderer;
$this->create();
}
//tell the widget to build the query, execute it, and filter the data
private function create() {
$this->build_query();
$this->execute_query();
$this->filter_data();
}
//methods called by the model:
abstract protected function build_query();
protected function execute_query() {
//common method
}
abstract protected function filter_data();
//method called by controller to tranform data for view
//transform into JSON, an html entity etc
abstract protected function process_data();
//method called by the view
//output the markup based on the widget Type and interleave the processed data
abstract protected function render();
}
这是一个好的设计吗?如何改善?
我假设编写一个新的小部件将需要至少一些新代码来构建查询,并可能过滤数据,但是它应该能够将几乎所有其他功能都使用预先存在的代码,包括已经存在的渲染器。
我希望任何人都可以至少对此设计提供一些反馈。验证吗?
撕开。叫我一个白痴。也可以我可以用任何向前的牵引力。
一些具体问题:
Q1。作为Widget类的一部分或单独的类,实现渲染器的最佳方法是什么? 1a。如果分开,它将如何与小部件类交互?
Q2。我如何改善这种设计以简化新型小部件的创建?
Q3。最后,我觉得我在这里缺少关于数据封装的东西。数据封装如何与需求相关联并在这种情况下发挥作用?