我如何摆脱模型类中的视图方法

时间:2014-06-27 06:56:27

标签: php yii

在模型中,我总是创建一些仅在这样的视图中使用的方法:

<?php $this->widget('CGridView', [
'id' => 'sales-list',
'columns' => [
    [
        'header' => 'id',
        'name' => 'id',
        'type' => 'raw',
        'value' => '$data->getViewId()'
    ],
    [
        'header' => 'Int ID',
        'name' => 'Int_id',
        'value' => '$data->getInternalId()',
    ],

在模型中我有代码

public function getInternalId()
{
    ...
}

public function getViewId()
{
    ...
}

通过创建这种方法,我的模型迅速上升,我不喜欢这样。我想从其他模型方法中分离查看方法,最佳做法是什么?

2 个答案:

答案 0 :(得分:2)

您的模型变得庞大且笨重,因为您遵循&#34; Fat模型和瘦控制器&#34; 设计的推荐方式。正如您所注意到的,随着时间的推移,任何中型项目中的模型都会很快变得肥胖!

首先是一些理论

要解决这个问题,首先必须要了解模型不仅仅是类或对象。模型是一个层。

MVC作为设计模式的普及和出现背后的基本逻辑是Separation of Concerns的哲学。从根本上说,MVC中有两层:表示层和模型层。

表示层进一步细分为控制器,视图,小部件,模板,布局等。

类似地,模型层分为域对象,存储抽象和服务。

域对象是我们所认为的&#34;模型&#34;通常,活动记录可以被认为是存储抽象的一部分。

tl; dr version 基本上是可以有多个模型文件调用相同的activeRecord模式

如何瘦身模型!

首先将逻辑函数分成不同的组,例如,如果User模型包含一组用于身份验证的函数,一组函数用于分析报告使用情况,另一组函数用于计算/格式化数据视图(gridView,小部件,列表视图等)和另一组具有rulesrelations等所有人需要的核心操作的函数。将它们拆分为类似这样的类

class User extends CActiveRecord {
    public static function model($className=__CLASS__) {
        return parent::model($className);
    }
    // This slimmed used class contains only core functions like 
    // rules, relations, attributeLabels, and perhaps search usually functions generated by gii 
    // + anything you think will be needed by all the other models 
}

您的身份验证类看起来像这样

class UserAuthentication extends User { 
     public static function model($className=__CLASS__) {
          return parent::model($className);
     }
     // All functions only related to authentication
}

您的UI /格式化类看起来像这样

class UserUI extends User {
     public static function model($className=__CLASS__) {
           return parent::model($className);
     }
    // Only formatting and other view related functions 

}

您的Analatics /报告类看起来像这样

class UserReports extends User {
    public static function model($className=__CLASS__) {
          return parent::model($className);
     }
     // All functions that are used for reports 
}

理想情况下,您应将所有这些拆分为单独的模块,以及其他模型,例如报告模块将包含所有报告域对象。

这使得在大型团队中编程变得更容易。测试,UI,控制器,布局几乎所有东西都可以彼此独立编写,每个模块可以通过服务(第三个模型组件)像接口一样相互通信

答案 1 :(得分:0)

除非要覆盖该值,否则您必须为每个属性创建一个getVar()和setVar()方法。

例如。没关系: -

public function getName()
{
    return 'My name is '.$this->name;
}

虽然这不是必需的,因为它是自动生成的。

public function getName()
{
    return $this->name;
}

因此,你可以说

echo $model->name;
// or
echo $model->getName();

$model->name = 'Tom';
// or
$model setName('Tom')

不在模型中创建getter和setter方法。

参考文献: http://www.yiiframework.com/wiki/167/understanding-virtual-attributes-and-get-set-methods/