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;
}
}

PHP 设计模式系列 —— 资源库模式(Repository)的更多相关文章

  1. PHP设计模式系列 - 外观模式

    外观模式 通过在必需的逻辑和方法的集合前创建简单的外观接口,外观设计模式隐藏了调用对象的复杂性. 外观设计模式和建造者模式非常相似,建造者模式一般是简化对象的调用的复杂性,外观模式一般是简化含有很多逻 ...

  2. akka设计模式系列-While模式

    While模式严格来说是while循环在Akka中的合理实现.while是开发过程中经常用到的语句之一,也是绝大部分编程语言都支持的语法.但while语句是一个循环,如果循环条件没有达到会一直执行wh ...

  3. 【.Net设计模式系列】仓储(Repository)模式 ( 一 )

    开篇 2016新年伊始,望眼过去,不知不觉在博客园已经注册8个月啦,由于最近忙于工作,博客迟迟没有更新.直到最近一直研究.Net设计模式,对一些模式有所感悟,故拿出自己的心得与大家分享,在接下来的所有 ...

  4. Java设计模式系列 — 构造器模式

    想象下你有一个类,像下图所示有许多属性.假设你想让你的类不可变(顺便说一下,除非有一个好的理由不这样做,否则你应该坚持.但是我们会以另一种方式来达到要求.) public class User { p ...

  5. PHP设计模式系列 - 委托模式

    委托模式 通过分配或委托其他对象,委托设计模式能够去除核心对象中的判决和复杂的功能性. 应用场景 设计了一个cd类,类中有mp3播放模式,和mp4播放模式 改进前,使用cd类的播放模式,需要在实例化的 ...

  6. PHP设计模式系列 - 工厂模式

    工厂模式 提供获取某个对象实例的一个接口,同时使调用代码避免确定实例化基类的步骤. 工厂模式 实际上就是建立一个统一的类实例化的函数接口.统一调用,统一控制. 工厂模式是php项目开发中,最常用的设计 ...

  7. c++设计模式系列----builder模式

    看了好几处关于builder模式的书和博客,总感觉不是很清楚,感觉不少书上的说的也不是很准确.最后还是看回圣经<设计模式>.看了好久终于感觉明白了一点了. 意图: builder模式提出的 ...

  8. akka设计模式系列-Chain模式

    链式调用在很多框架和系统中经常存在,算不得上是我自己总结的设计模式,此处只是简单介绍在Akka中的两种实现方式.我在这边博客中简化了链式调用的场景,简化后也更符合Akka的设计哲学. trait Ch ...

  9. akka设计模式系列-Aggregate模式

    所谓的Aggregate模式,其实就是聚合模式,跟masterWorker模式有点类似,但其出发点不同.masterWorker模式是指master向worker发送命令,worker完成某种业务逻辑 ...

随机推荐

  1. Failed to execute operation: No such file or directory(systemctl enable iptables.service)

    在保存Iptables配置时:systemctl enable iptables.service 出现错误: Failed to execute operation: No such file or ...

  2. 3.3 x86指令简介

    计算机组成 3 指令系统体系结构 3.3 x86指令简介 x86指令种类繁多,数量庞大.在这一节我们将会学习x86指令的分类,并分析其中最为基础的一部分指令. 通常一个指令系统主要包括这几类指令.运算 ...

  3. java通过java.net.URL发送http请求调用接口

    一般在*.html,*.jsp页面中我们通过使用ajax调用接口,这个是我们通常用的.对于这些接口,大都是本公司写的接口供自己调用,所以直接用ajax就可以.但是,如果是多家公司共同开发一个东西,一个 ...

  4. Python下图片的高斯模糊化的优化

    资源下载 #本文PDF版下载 Python下图片的高斯模糊化的优化(或者单击我博客园右上角的github小标,找到lab102的W6目录下即可) #本文代码下载 高斯模糊(一维)优化代码(和本文方法集 ...

  5. quartz---(1)

    Quartz Quartz是什么? 简单的一些例子 Quartz是什么 简单的认为Quartz是是一个定时器. 1.1. 下载 http://www.quartz-scheduler.org/down ...

  6. python 使用yield进行数据的流式处理

    demo:从文件中取包含字符“a”的5行数据做一次批处理!!! # coding: utf-8 import time def cat(f): for line in f: yield line de ...

  7. xrat CC特征

    ["6", 11818669.0, 8326.0, 599.75, 19705.992496873696, 13.882451021258857, 0.07203338938265 ...

  8. 信号处理函数的返回sigsetjmp/siglongjmp

    由于在信号处理期间自动屏蔽了正在被处理的信号,而使用setjmp/longjmp跳出信号处理程序时又不会自动将 信号屏蔽码修改会原来的屏蔽码,从而引起该信号被永久屏蔽. 可以使用sigsetjmp/s ...

  9. pip install flask 安装失败

    地址:http://www.zhihu.com/question/21492455

  10. 封装ajax函数

    <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title> ...