3

我参与的许多 Web 应用程序项目都达到了

  1. 应用程序希望持久化数据采用特定格式

  2. 如果持久化的数据偏离该格式,应用程序将停止

  3. 旧的“神秘代码”以错误的格式保存数据

这通常会导致应用程序开发人员将模型代码与大量验证条件混为一谈。那是

function save()
{
    if($model->getSomeProp() == 'bad value')
    {
        $model->setSomeProp('good default value');
    }

    return parent::save();
}        

是否有更好的模式和/或系统来处理这些情况,并且所述模式和/或系统不依赖于让开发人员为每个版本编写完美的迁移脚本和/或验证代码?我特别感兴趣的是其他开发人员如何处理这些(根据我的经验)常见的长期问题。

专门寻找 LAMP Stack/PHP 解决方案,但来自其他常见中间件语言/平台(ruby、python 等)的解决方案和方法非常受欢迎。

4

2 回答 2

2

至少您正在尽可能接近数据库交互来处理这种类型的行为,如果您的代码库中充斥着这些类型的检查,情况可能会更糟。

如果我的任务是清理这种类型的东西,我想我要做的第一件事就是设置抛出自定义异常代码的方法,这样我就可以记录调用代码并找到我的应用程序的哪个部分正在格式化数据不正确的时尚。

例如,您可以执行以下操作:

class CustomException extends Exception
{
    const CODE_BAD_FORMAT = 1;

    protected code;

    public function setCode($code)
    {
        $this->code = $code;
    }

    public function getCode()
    {
        return $this->code;
    }
}

class Model extends ParentModel
{
    function save()
    {
        if ($model->getSomeProp() == 'bad value') {
            $badValueFound = true;
            $model->setSomeProp('good default value');
        }

        // Now that you are using try/catches you don't need a return value
        parent::save();

        if ($badValueFound) {

            $e = new CustomException();
            $e->setCode(CustomException::CODE_BAD_FORMAT);

            throw $e;
        }
    }
}

// Calling code
try {
    $model = new Model();

    $model->setSomeProp('ohnoes im bad format');

    $model->save();

} catch (Exception $e) {

    if ($e->getCode() === CustomException::CODE_BAD_FORMAT) {
        error_log(__METHOD__ . ': Called save with bad format'); 
    } else {
        throw $e; // Some other exception occurred b/c the code() didn't line up so bubble up
    }
}

// All is well b/c made it through the try / catch block... so onto the next logic

现在,您可以调用 save(),如果遇到错误格式,您可以抛出异常并检查调用中的代码,如果代码匹配(预期错误格式),那么您可以实现一些日志记录跟踪调用码点。

另外,你不会在这个过程中破坏任何东西,因为保存仍然会发生,但是你必须确保对 save() 的任何调用都包含在 try/catch 块中,否则如果没有被捕获,你会得到异常适当地。

另一个想法可能是跟踪模型类中的错误格式构造,这样您就不会最终在整个地方复制相同的字符串:

class Model
{
    const BAD_FORMAT_MALFORMED_NAME = 'format for a malformed name';
    const BAD_FORMAT_MALFORMED_ADDRESS = 'format for malformed address';
}

....
if($model->getSomeProp() === self::BAD_FORMAT_MALFORMED_NAME) {
....
于 2011-12-13T05:17:20.287 回答
2

我们使用配置文件提供的应在每个已处理项目上执行的步骤列表。这使得验证、数据的轻微变化、查找、检索和合并来自外部源的某些属性等成为可能。

虽然现在它基于一组实现 abstract 的 Ruby 类,Step根据 yaml 配置工作,但我想在下一次重写中我会使用纯 Ruby DSL。

所以最后,你会得到这样的东西:

HealingProcessor.on(impure_data) {
  replace_bad_value :field => :some_prop, :bad_value => 'bad value', :good_value => 'good_default_value'
  # etc
}
于 2011-12-13T00:33:49.297 回答