1

我在验证引用其他模型的模型时遇到了问题。

我有一个“用户”模型和一个“配置文件”模型。我想创建配置文件,但我需要检查用户是否真的存在。

在我的配置文件模型中,我有一个方法“validateUser”,但我要么必须向数据库中的特定表写入查询,要么必须创建一个用户模型对象并调用存在(id)。

这两种选择似乎都有很多缺点。表名可能会改变我必须检查所有使用它的模型。对于用户模式对象,我必须在配置文件模型中创建一个对象或注入它。

解决这个问题的最佳方法是什么?

4

1 回答 1

1

厄运之域..

在现实世界的情况下,验证很少是一个简单的过程。相反,您有几个不相关的问题:

  • 检查实例内的数据是否符合业务规则
  • 确保实例状态不与其他域结构冲突
  • 根据现有数据和存储限制验证信息的完整性

如果您使用活动记录来表示您的域模型 (不要与 MVC 中的 M 混淆),那么所有这三个方面都将成为单个对象的责任。

这就是你现在所拥有的。

但是有希望..

最好的选择是将所有这些职责分开(所有这些都是SRP。基本上,您所做的是将当前设置划分为不同的结构组:

  • 域对象:用于处理域实体的特定规则

  • 数据映射器:用于存储抽象

  • services:用于域对象和映射器(或其他域对象)之间的交互

由于您的问题有些令人困惑(用户和配置文件以及保存和验证,然后一些东西不存在),我不确定我是否理解正确,但这里有一个小例子:

public function createProfile( $id, $email, $name )
{
    $account = new Account;
    $account->setId( $id );

    $accountMapper = new AccountMapper( $pdo ); // explained below

    if ( $accountMapper->fetch( $account ) === false )
    {
        $this->errors[] = .. something about missing account
        return;
    }

    $profile = new Profile;
    $profile->setEmail( $email )
            ->setName( $name );

    if ( $profile->isValid() === false )
    {
        $this->errors[] = .. something about invalid profile
        return;
    }
    
    try
    {
        $profileMapper = new ProfileMapper( $pdo ); // explained below
        $profileMapper->store( $profile );
    }
    catch ( Exception $e )
    {
        $this->errrors[] = .. something about failing to create profile
        return;
    }

    $account->addProfile( $profile );
    $accountMapper->store( $account );
}

这是一个极其简化的例子。尤其是在映射器被初始化的地方,因为现实世界中的那部分将由某个工厂处理。有点像这篇文章中描述的。

这里的重点是域数据的验证和数据库完整性的保险是分开进行的。用于与数据库交互的底层 API 实际上会返回错误代码是您违反UNIQUE KEYFOREIGN KEY任何其他约束,然后您可以使用它来确定出了什么问题。

该方法本身将是服务的一部分(在这种情况下 - 一些管理用户帐户的服务)。

注意:如果您的应用程序需要在每个操作中执行多个 SQL 交互,并且这些交互需要作为具有回滚能力的事务来完成,那么,您应该考虑实现Units of Work ,而不是直接使用数据映射器。要了解 UoW,您必须阅读Patterns of Enterprise Application Architecture,因为它是一个非常广泛的主题。

于 2013-09-11T21:44:35.447 回答