你将如何组织一个在两个模型上运行的代码?

时间:2016-09-17 17:08:52

标签: php

让我们说一个新文章正在创建,它也必须被记录,所以:

INSERT INTO article VALUES ($name);
INSERT INTO logs VALUES ($name, GET_LAST_ID());

代码:

class Article
{
    public function add($name)
    {
        Sql::exec('INSERT INTO article VALUES ('.$name.')');
    }
}

class Log
{
    public function add($name)
    {
        Sql::exec('INSERT INTO logs VALUES ('.$name.', GET_LAST_ID());
    }
}
控制器中的

$article->add('s');
$log->add('s');

当然(除了SQL劫持)它很糟糕,它可以随时重复,所以COPY + PASTE就是这样。你会如何组织新课程?它应该是AddArticleAndLogIt?当然不是。

2 个答案:

答案 0 :(得分:1)

我会为那两个DAL(我不称它们为模型)对象创建接口。其中一个实现变体是这个Sql :: ...的东西。然后,我会创建IArticleOperations服务,它接受注入的IArticle和ILog实现与方法添加,我猜。然后我将创建它的实现,其中方法add从DAL对象调用这两个方法。

我怀疑你的问题可能有点不同。您是否希望每次添加新业务模型时都记录(不仅仅是本文)?

答案 1 :(得分:1)

我认为很难对这个问题有正确答案,因为这取决于您的偏好(例如,您不喜欢观察者/触发器)和您的代码。数据插入器服务也是一个不错的选择,例如:

class DataPersister
{
    public function create($table, array $data)
    {
        // This of course is a very bad implementation, I would
        // use placeholders, but it follows the example code you posted.
        Sql::exec(sprintf(
            'INSERT INTO %s (%s) VALUES (%s)',
            $table,
            implode(', ', array_keys($data)),
            '"' . implode('", "', $data) . '"'
        ));

        $this->log($data);
    }

    public function log(array $data)
    {
        Sql::exec('INSERT INTO logs VALUES (' . $data['name'] . ', GET_LAST_ID());
    }
}

您可以将其用作:

$articleData = [ 'name' => 's' ];
$persister->create('articles', $articleData);

$commentData = [ ... ];
$persister->create('comments', $commentData);