为什么要打扰仓库

时间:2019-01-14 16:43:04

标签: php design-patterns orm repository datamapper

我问这个问题有点愚蠢,因为有很多资源在讨论和解释映射器和存储库,但是我似乎无法解决。因此,我创建了一些示例代码来解释我的困惑。请注意,我不知道这段代码是否可以正常工作,我以编写示例为例。

这将是实体/类(<body> <script> $("#envoyer").click(function(){ $.ajax({ url : 'send_mail.php', type : 'POST', data : 'dataType=json' success: handle }); }); function handle(result, status) { //setting the text extracted from json object $(“#result”).append(`<div> ${result.a} </div>`) } </script> </body>

Quote.php

这将是映射器(class Quote { private $id; private $author; private $content; public function getId() { return $this->id; } public function getAuthor() { return $this->author; } public function getContent() { return $this->content; } public function setId(int $id) { $this->id = $id; } public function getAuthor(string $author) { $this->author = $author; } public function setContent(string $content) { $this->content = $content; } }

QuoteMapper.php

最后但并非最不重要的是,这将是存储库(class QuoteMapper { private $PDO; public function __construct(PDO $PDO) { $this->PDO = $PDO; } public function find(int $id = null, string $search = null) { if (!empty($id) && !empty($search)) { //Search for id and search word $stmt = $this->PDO->prepare("SELECT `id`, `author`, `content` FROM `quotes` WHERE `id` = :id AND `content` LIKE :search LIMIT 1"); $stmt->bindParam('search', $search, PDO::PARAM_INT); $stmt->bindParam('id', $id, PDO::PARAM_INT); else if (!empty($id)) { //search for id only $stmt = $this->PDO->prepare("SELECT `id`, `author`, `content` FROM `quotes` WHERE `id` = :id AND `content` LIKE :search LIMIT 1"); $stmt->bindParam('id', $id, PDO::PARAM_INT); } else if (!empty($search)) { //search for search word only $stmt = $this->PDO->prepare("SELECT `id`, `author`, `content` FROM `quotes` WHERE `id` = :id AND `content` LIKE :search LIMIT 1"); $stmt->bindParam('search', $search, PDO::PARAM_INT); } $stmt->execute(); $stmt->bindColumn('id', $id); $stmt->bindColumn('author', $author); $stmt->bindColumn('content', $content); $stmt->fetch(); $quote = new Image(); $quote->setId($title); $quote->setAuthor($source); $quote->setContent($alternative); return $image; } public function save(Quote $quote) { //A save function } public function delete(Quote $quote) { //A delete function } }

QuoteRepository.php

据我了解,我的映射器不是“错误的”,因为映射器的目的是执行诸如从持久性数据存储(例如MySQL)获取和设置数据之类的事情

  

数据映射器是执行双向数据访问的层   在持久数据存储(通常是关系数据)之间进行数据传输   数据库)和内存中的数据表示形式(域层)。   来自Wikipedia

但是我的存储库实际上什么也没做。它只是将函数调用传递给映射器?因此,我只能假设我的映射器包含应该在存储库中的代码,但是那是什么代码?也许我完全误解了数据映射器和存储库如何协同工作。

如果我做的任何其他事情是错误的或被认为是不正确的做法,我想听听。我真的在想办法! :)

1 个答案:

答案 0 :(得分:2)

DataMapper 是将应用程序与具体数据库隔离的层。它将对象转换为数据库的记录,并将记录转换为对象。 DataMapper使我们能够使用数据库,并且不知道我们使用的是哪种RDBMS。示例:

interface DataMapperInterface
{

    /**
     * Find objects by a criteria
     *
     * @param array $criteria Search params
     * @return Quote[] Found entities
     */
    public function find(array $criteria);

    /**
     * Insert an object into a database
     *
     * @param Quote $object Object that will be inserted
     */
    public function insert(Quote $object);

    /**
     * Update an object date in a database
     *
     * @param Quote $object Object that will be updated
     */
    public function update(Quote $object);

    /**
     * Remove an object from a database
     *
     * @param Quote $object Object that will be removed
     */
    public function delete(Quote $object);
}

Repository 是用于封装查询构建逻辑的层。它使我们能够处理对象的集合,并且不知道要使用数据库的任何东西。

class Repository
{

   /**
    * @var DataMapperInterface Mapper to transform objects
    */ 
   protected $mapper;

   /**
    * Constructor
    *
    * @param DataMapperInterface $mapper Mapper to transform objects
    */
   public function __construct(DataMapperInterface $mapper)
   {
       $this->mapper = $mapper;
   }

   /**
    * Find all objects
    *
    * @return Quote[] Found entities
    */
   public function findAll()
   {
       return $this->mapper->find([]);
   }

   /**
    * Find an object by an identifier
    *
    * @return Quote[] Found entities
    */
   public function findById(integer $id)
   {
       $criteria = ['id' => $id];
       return $this->mapper->find($criteria);
   }

   /**
    * Find objects by an author name
    *
    * @return Quote[] Found entities
    */
   public function findByAuthor($name)
   {
       $criteria = ['author' => $name];
       return $this->mapper->find($criteria);
   }

   /**
    * Save an object into the repository
    */
   public function save(Quote $object)
   {
       if (empty($object->id)) {
           $this->mapper->insert($object);
       } else {
           $this->mapper->update($object);
       }
a    }

   /**
    * Remove an object from the repository
    */
   public function remove(Quote $object)
   {
       $this->mapper->delete($object);
   }
}

这是一个非常简单的实例,在实际应用中这更困难:查询更大,存储库可以与许多其他模式配合使用(Query Object来查询构建,Unit of Work来跟踪更改,{ {3}}以避免重复加载对象等)