繁体   English   中英

设计模式:数据映射器+依赖项注入?

[英]Design patterns: data mapper + dependency injection?

我正在遵循数据映射器指南 但是它在mapper类中有一个模型类。 所以我通过使用依赖注入对其进行了修改。

模型,

class User
{
    /**
     * @var int
     */
    protected $userId;

    /**
     * @var string
     */
    protected $username;

    /**
     * @var string
     */
    protected $email;

    /**
     * @param null $id
     * @param null $username
     * @param null $email
     */
    public function __construct($id = null, $username = null, $email = null)
    {
        $this->userId = $id;
        $this->username = $username;
        $this->email = $email;
    }

    /**
     * @return int
     */
    public function getUserId()
    {
        return $this->userId;
    }

    /**
     * @param int $userId
     */
    public function setUserID($userId)
    {
        $this->userId = $userId;
    }

    /**
     * @return string
     */
    public function getUsername()
    {
        return $this->username;
    }

    /**
     * @param string $username
     */
    public function setUsername($username)
    {
        $this->username = $username;
    }

    /**
     * @return string
     */
    public function getEmail()
    {
        return $this->email;
    }

    /**
     * @param string $email
     */
    public function setEmail($email)
    {
        $this->email = $email;
    }
}

映射器

class UserMapper
{
    public function __construct($model)
    {
        $this->model = $model;
    }

    public function findAll()
    {
        $resultSet = array(
            array('userid' => 1, 'username' => 'Odysseus', 'email' => 'Odysseus@ithaca.gr'),
            array('userid' => 2, 'username' => 'Penelope', 'email' => 'Penelope@ithaca.gr')
        );

        $entries   = array();

        foreach ($resultSet as $row) {
            $entries[] = $this->mapObject($row);
        }

        return $entries;
    }

    protected function mapObject(array $row)
    {
        $this->model->setUserID($row['userid']);
        $this->model->setUsername($row['username']);
        $this->model->setEmail($row['email']);

        return $this->model;
    }
}

用法,

$model = new User();
$mapper = new UserMapper($model);
$users = $mapper->findAll();
print_r($users);

结果(不正确),

Array
(
    [0] => User Object
        (
            [userId:protected] => 2
            [username:protected] => Penelope
            [email:protected] => Penelope@ithaca.gr
        )

    [1] => User Object
        (
            [userId:protected] => 2
            [username:protected] => Penelope
            [email:protected] => Penelope@ithaca.gr
        )

)

但它会返回正确的结果,而无需进行依赖注入,

protected function mapObject(array $row)
{
    $entry = new User();
    $entry->setUserID($row['userid']);
    $entry->setUsername($row['username']);
    $entry->setEmail($row['email']);

    return $entry;
}

结果,

Array
(
    [0] => User Object
        (
            [userId:protected] => 1
            [username:protected] => Odysseus
            [email:protected] => Odysseus@ithaca.gr
        )

    [1] => User Object
        (
            [userId:protected] => 2
            [username:protected] => Penelope
            [email:protected] => Penelope@ithaca.gr
        )

)

那么,如何将依赖注入数据映射器一起使用以返回正确的结果? 有任何想法吗?

编辑:

class UserMapper
{
    protected function mapObject(array $row)
    {
        return new User($row['userid'], $row['username'], $row['email']);
    }
}

只是不要。 唯一的解决方案是注入一个工厂,然后创建模型对象,但是正如您在本主题另一个问题中所说明的那样,这里实际上不需要额外的抽象级别。 数据映射器本身负责创建对象。


这是使用依赖项注入的解决方案,您可以在其中将对象创建委托给工厂。 但是我敢肯定, 您将不需要它 在大多数情况下,将数据映射器与其映射的模型耦合起来是一件合理的事情。

class UserMapper
{
    public function __construct(UserFactory $userFactory)
    {
        $this->userFactory = $userFactory;
    }

    protected function mapObject(array $row)
    {
        return $userFactory->createUser($row['userid'], $row['username'], $row['email']);
    }
}

interface UserFactory
{
    public function createUser($id, $name, $email);
}

class DefaultUserFactory implements UserFactory
{
    public function createUser($id, $name, $email)
    {
        return new User($id, $name, $email);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM