基于实体的密钥的人类可读表示的适当位置

时间:2012-07-01 19:18:18

标签: zend-framework doctrine-orm entity static-methods

首先是一些背景。我们最近从基于Zend_Db_Table的解决方案转换为基于实体的解决方案(Doctrine)。随着我们的应用程序的增长,表类变得更加丑陋和丑陋。一些表使用ENUM列来存储基于字符串的键,这些键使用静态方法转换为人类可读的字符串。像这样:

public static function getProductType($productKey)
{
    if (!array_key_exists($productKey, self::$productTypes)) {
        return null;
    }
    return self::$productTypes[$productKey];
}

public static function getProductTypes()
{
    return self::$productTypes;
}

在迁移到基于实体的系统时,我试图尽可能避免使用静态方法。我将键移动到值转换为视图助手,并将其称为一天。最后,我发现这还不够,因为我们需要在JSON对象中返回它们,这些对象发生在表示层之外(即不能直接访问视图助手)。

有没有人对这些方法的适当位置有任何理论?我应该创建单独的对象来执行从键到人类可读值的转换,在实体对象上实现静态方法,还是其他什么?

1 个答案:

答案 0 :(得分:0)

我的理论是,这应该在模型本身中完成。但有时在处理复杂模型时,我喜欢创建一个单独的类来处理该模型的任何特殊“表示”。它将模型作为参数并封装表示逻辑。

所以使用你的例子,也许是这样的:

class Model_Product
{
    public static function getAllTypes()
    {
        return array(/* key-value pairs */);
    }

    //returns non human readable value
    public function getType()
    {
        return $this->_type;
    }
}

class Model_Product_Presenter
{
    protected $_model;

    public function __construct(Model_Product $model)
    {
        $this->_model = $model; 
    }

    //returns human readable value
    public function getType()
    {
        $types = $this->_model->getAllTypes();

        if (!array_key_exists($this->_model->type, $types)) {
            return null;
        }
        return $types[$this->_model->type];
    }

    public function getDateCreated($format = "Y-m-d")
    {
        return date($format,$this->_model->timestamp);
    }
}

您可以进一步创建基本演示者类来定义任何常见任务,即将时间戳转换为日期,格式化数字等。

<强>更新 对于匿名访问产品类型列表,我认为通过静态方法使其成为产品模型的责任没有任何损害。并非所有静态方法都是邪恶的。在我看来,为此目的使用静态方法很好,因为它声明了一个全局常量。

在更复杂的场景中,我会将此职责委托给一个单独的类,如Model_ProductType。以下是生产中这种复杂模型的一个例子:

https://github.com/magento/magento2/blob/master/app/code/core/Mage/Catalog/Model/Product/Type.php