数据映射器是一种数据访问层,用于将数据在持久性数据存储(一般是一个关系数据库)和内存中的数据表示(领域层)之间进行双向传输。该模式的目标是为了将数据的内存表示、持久存储、数据访问进行分离。 该层由一个或多个映射器(或数据访问对象)组成,而且进行数据的转换。映射器实现的范围有所不一样。 通用映射器将处理许多不一样的域实体类型,专用映射器将处理一个或几个。php
数据库对象关系映射器( ORM ):Doctrine2 使用的 DAO,名字叫作 “EntityRepository”。laravel
<?php namespace DesignPatterns\Structural\DataMapper; class User { /** * @var string */ private $username; /** * @var string */ private $email; public static function fromState(array $state): User { // 在你访问的时候验证状态 return new self( $state['username'], $state['email'] ); } public function __construct(string $username, string $email) { // 先验证参数再设置他们 $this->username = $username; $this->email = $email; } /** * @return string */ public function getUsername() { return $this->username; } /** * @return string */ public function getEmail() { return $this->email; } }
<?php namespace DesignPatterns\Structural\DataMapper; class UserMapper { /** * @var StorageAdapter */ private $adapter; /** * @param StorageAdapter $storage */ public function __construct(StorageAdapter $storage) { $this->adapter = $storage; } /** * 根据 id 从存储器中找到用户,并返回一个用户对象 * 在内存中,一般这种逻辑将使用 Repository 模式来实现 * 然而,重要的部分是在下面的 mapRowToUser() 中,它将从中建立一个业务对象 * 从存储中获取的数据 * * @param int $id * * @return User */ public function findById(int $id): User { $result = $this->adapter->find($id); if ($result === null) { throw new \InvalidArgumentException("User #$id not found"); } return $this->mapRowToUser($result); } private function mapRowToUser(array $row): User { return User::fromState($row); } }
<?php namespace DesignPatterns\Structural\DataMapper; class StorageAdapter { /** * @var array */ private $data = []; public function __construct(array $data) { $this->data = $data; } /** * @param int $id * * @return array|null */ public function find(int $id) { if (isset($this->data[$id])) { return $this->data[$id]; } return null; } }
<?php namespace DesignPatterns\Structural\DataMapper\Tests; use DesignPatterns\Structural\DataMapper\StorageAdapter; use DesignPatterns\Structural\DataMapper\User; use DesignPatterns\Structural\DataMapper\UserMapper; use PHPUnit\Framework\TestCase; class DataMapperTest extends TestCase { public function testCanMapUserFromStorage() { $storage = new StorageAdapter([1 => ['username' => 'domnikl', 'email' => 'liebler.dominik@gmail.com']]); $mapper = new UserMapper($storage); $user = $mapper->findById(1); $this->assertInstanceOf(User::class, $user); } /** * @expectedException \InvalidArgumentException */ public function testWillNotMapInvalidData() { $storage = new StorageAdapter([]); $mapper = new UserMapper($storage); $mapper->findById(1); } }
PHP 互联网架构师 50K 成长指南+行业问题解决总纲(持续更新)shell
面试10家公司,收获9个offer,2020年PHP 面试问题数据库
★若是喜欢个人文章,想与更多资深开发者一块儿交流学习的话,获取更多大厂面试相关技术咨询和指导,欢迎加入咱们的群啊,暗号:phpzh(群ID:856460874)。设计模式
内容不错的话但愿你们支持鼓励下点个赞/喜欢,欢迎一块儿来交流;另外若是有什么问题 建议 想看的内容能够在评论提出架构