设计模式:数据映射器+依赖注入?
Design patterns: data mapper + dependency injection?
我正在关注 data mapper guide。但是它在映射器class中有一个模型class。所以我通过使用依赖注入对其进行了修改。
型号,
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
)
)
但它 return 是没有依赖注入的正确结果,
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
)
)
那么,我如何使用依赖注入 和 数据映射器来 return 正确的结果?有什么想法吗?
编辑:
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);
}
}
我正在关注 data mapper guide。但是它在映射器class中有一个模型class。所以我通过使用依赖注入对其进行了修改。
型号,
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
)
)
但它 return 是没有依赖注入的正确结果,
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
)
)
那么,我如何使用依赖注入 和 数据映射器来 return 正确的结果?有什么想法吗?
编辑:
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);
}
}