1、模式定義
Repository 是一個獨立的層,介於領域層與資料對應層(資料訪問層)之間。它的存在讓領域層感覺不到資料訪問層的存在,它提供一個類似集合的介面提供給領域層進行領域對象的訪問。Repository 是倉庫管理員,領域層需要什麼東西只需告訴倉庫管理員,由倉庫管理員把東西拿給它,並不需要知道東西實際放在哪。
Repository 模式是架構模式,在設計架構時,才有參考價值。應用 Repository 模式所帶來的好處,遠高於實現這個模式所增加的代碼。只要項目分層,都應當使用這個模式。
2、UML類圖
3、範例程式碼
Post.php
<?php
namespace DesignPatterns\More\Repository;
/**
* Post 類
* @package DesignPatterns\Repository
*/
class Post
{
/**
* @var int
*/
private $id;
/**
* @var string
*/
private $title;
/**
* @var string
*/
private $text;
/**
* @var string
*/
private $author;
/**
* @var \DateTime
*/
private $created;
/**
* @param int $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @param string $author
*/
public function setAuthor($author)
{
$this->author = $author;
}
/**
* @return string
*/
public function getAuthor()
{
return $this->author;
}
/**
* @param \DateTime $created
*/
public function setCreated($created)
{
$this->created = $created;
}
/**
* @return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* @param string $text
*/
public function setText($text)
{
$this->text = $text;
}
/**
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
}
PostRepository.php
<?php
namespace DesignPatterns\More\Repository;
use DesignPatterns\More\Repository\Storage;
/**
* Post 對應的 Repository
* 該類介於資料實體層(Post) 和訪問對象層(Storage)之間
*
* Repository 封裝了持久化對象到資料存放區器以及在展示層顯示物件導向的視圖操作
*
* Repository 還實現了領域層和資料對應層的分離和單向依賴
*
* PostRepository 類
* @package DesignPatterns\Repository
*/
class PostRepository
{
private $persistence;
public function __construct(Storage $persistence)
{
$this->persistence = $persistence;
}
/**
* 通過指定id返回Post對象
*
* @param int $id
* @return Post|null
*/
public function getById($id)
{
$arrayData = $this->persistence->retrieve($id);
if (is_null($arrayData)) {
return null;
}
$post = new Post();
$post->setId($arrayData['id']);
$post->setAuthor($arrayData['author']);
$post->setCreated($arrayData['created']);
$post->setText($arrayData['text']);
$post->setTitle($arrayData['title']);
return $post;
}
/**
* 儲存指定對象並返回
*
* @param Post $post
* @return Post
*/
public function save(Post $post)
{
$id = $this->persistence->persist(array(
'author' => $post->getAuthor(),
'created' => $post->getCreated(),
'text' => $post->getText(),
'title' => $post->getTitle()
));
$post->setId($id);
return $post;
}
/**
* 刪除指定的 Post 對象
*
* @param Post $post
* @return bool
*/
public function delete(Post $post)
{
return $this->persistence->delete($post->getId());
}
}
Storage.php
<?php
namespace DesignPatterns\More\Repository;
/**
* Storage介面
*
* 該介面定義了訪問資料存放區器的方法
* 具體的實現可以是多樣化的,比如記憶體、關係型資料庫、NoSQL資料庫等等
*
* @package DesignPatterns\Repository
*/
interface Storage
{
/**
* 持久化資料方法
* 返回新建立的對象ID
*
* @param array() $data
* @return int
*/
public function persist($data);
/**
* 通過指定id返回資料
* 如果為空白返回null
*
* @param int $id
* @return array|null
*/
public function retrieve($id);
/**
* 通過指定id刪除資料
* 如果資料不存在返回false,否則如果刪除成功返回true
*
* @param int $id
* @return bool
*/
public function delete($id);
}
MemoryStorage.php
<?php
namespace DesignPatterns\More\Repository;
use DesignPatterns\More\Repository\Storage;
/**
* MemoryStorage類
* @package DesignPatterns\Repository
*/
class MemoryStorage implements Storage
{
private $data;
private $lastId;
public function __construct()
{
$this->data = array();
$this->lastId = 0;
}
/**
* {@inheritdoc}
*/
public function persist($data)
{
$this->data[++$this->lastId] = $data;
return $this->lastId;
}
/**
* {@inheritdoc}
*/
public function retrieve($id)
{
return isset($this->data[$id]) ? $this->data[$id] : null;
}
/**
* {@inheritdoc}
*/
public function delete($id)
{
if (!isset($this->data[$id])) {
return false;
}
$this->data[$id] = null;
unset($this->data[$id]);
return true;
}
}