php 常用五种模式
/* 设计模式之单例模式
$_instance 必须声明为静态的私有变量
构造函数必须声明为私有,防止外部程序 new 类从而失去单例模式的意义
getInstance() 方法必须设置为公有的,必须调用此方法以返回实例的一个引用
:: 操作符只能访问静态变量和函数 new 对象会消耗内存
使用场景:最常用的地方是数据库连接
使用单例模式生成一个对象后,该对象可以被其它众多对象所使用
【单例模式适用场景】
1、当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
2、当这个唯一实例应该是通过子类化可扩展的。并且用户应该无需更改代码就能使用一个扩展的实例时。
*/
class single {
// 在此属性保存实例
private static $_instance;
// 构造函数声明为 private,防止直接创建对象
private function __construct() {
echo 'this is contructor ';
}
// 单例方法
public static function get_instance() {
if(!isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
// 阻止用户复制对象实例
private function __clone() {
trigger_error('not allow ', E_USER_ERROR);
}
public function test() {
echo 'test method ! ';
}
}
$test = single::get_instance();
$test->test();
工厂方法
// 共同接口
interface Sender {
public function send();
}
// 两个实现类
class MailSender implements Sender {
public function send() {
echo "this is mailsender ! ";
}
}
class SmsSender implements Sender {
public function send() {
echo "this is sms sender !";
}
}
// 工厂类接口
interface Provider {
public function produce();
}
// 两个工厂类
class SendMailFactory implements Provider {
public function produce() {
return new MailSender();
}
}
class SendSmsFactory implements Provider {
public function produce() {
return new SmsSender();
}
}
//测试用:
$provider = new SendMailFactory();
$sender = $provider->produce();
$sender->Send();
观察者模式
/* 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新, 又称为发布-订阅(Publish-Subscribe)模式、模型-视图(Model-View)模式、源-监听(Source-Listener)模式、或从属者(Dependents)模式
【观察者模式中主要角色】
抽象主题(Subject)角色:主题角色将所有对观察者对象的引用保存在一个集合中,每个主题可以有任意多个观察者。抽象主题提供了增加和删除观察者对象的接口。
抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在观察的主题发生改变时更新自己。
具体主题(ConcreteSubject)角色:存储相关状态到具体观察者对象,当具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个具体子类实现。
具体观察者(ConcretedObserver)角色:存储一个具体主题对象,存储相关状态,实现抽象观察者角色所要求的更新接口,以使得其自身状态和主题的状态保持一致。
【观察者模式的优点和缺点】
观察者模式的优点:
1、观察者和主题之间的耦合度较小;
2、支持广播通信;
观察者模式的缺点:
1、由于观察者并不知道其它观察者的存在,它可能对改变目标的最终代价一无所知。这可能会引起意外的更新。
【观察者模式适用场景】
1、当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。
2、当对一个对象的改变需要同时改变其它对象,而不知道具体有多少个对象待改变。
3、当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换句话说,你不希望这些对象是紧密耦合的。
*/
// 抽象主题角色
interface Subject {
// 增加一个新的观察者对象
public function attach(Observer $observer);
// 删除一个已注册过的观察者对象
public function detach(Observer $observer);
// 通知所有注册过的观察者对象
public function notifyObservers();
}
// 具体主题角色
class ConcreteSubject implements Subject {
private $_observers;
public function __construct() {
$this->_observers = array();
}
public function attach(Observer $observer) {
return array_push($this->_observers, $observer);
}
public function detach(Observer $observer) {
$index = array_search($observer, $this->_observers);
if($index === false || !array_key_exists($index, $this->_observers)) {
return false;
}
unset($this->_observers[$index]);
return true;
}
public function notifyObservers() {
if(!is_array($this->_observers)) {
return false;
}
foreach($this->_observers as $observer) {
$observer->update();
}
return true;
}
}
//抽象观察者角色
interface Observer {
// 更新方法
public function update();
}
class ConcreteObserver implements Observer {
//观察者的名称
private $_name;
public function __construct($name) {
$this->_name = $name;
}
// 更新方法
public function update() {
echo ' Observer ' . $this->_name . ' has notified ';
}
}
$subject = new ConcreteSubject();
// 添加第一个观察者
$observer1 = new ConcreteObserver('long');
$subject->attach($observer1);
echo "111 : <br />";
$subject->notifyObservers();
// 添加第二个观察者
$observer2 = new ConcreteObserver('Lin');
$subject->attach($observer2);
echo "<br /> 2222 <br />";
$subject->notifyObservers();
//删除第一个观察者
$subject->detach($observer1);
echo "<br /> 333 <br />";
echo $subject->notifyObservers();
命令模式
/* 命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行。这个过程好在,三者相互解耦,任何一方都不用去依赖其他人,只需要做好自己的事儿就行,司令员要的是结果,不会去关注到底士兵是怎么实现的。
Invoker是调用者(司令员),Receiver是被调用者(士兵),MyCommand是命令,实现了Command接口,持有接收对象.命令模式的目的就是达到命令的发出者和执行者之间解耦,实现请求和执行分开
*/
// 接口
interface Command {
public function exe();
}
// 执行命令者(请来一个人)
class Receiver {
public function action() {
echo "Command received ! ";
}
}
// 命令(给予上面的人一个命令)
class MyCommand implements Command {
private $receiver;
public function __construct($receiver) {
$this->receive = $receiver;
}
public function exe() {
$this->receive->action();
}
}
// 发出命令(下命令)
class Invoker {
private $command;
public function __construct($command) {
$this->command = $command;
}
public function action() {
$this->command->exe();
}
}
// 示例
$receiver = new Receiver();
$cmd = new MyCommand($receiver);
$invoker = new Invoker($cmd);
$invoker->action();
策略模式
/* 定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。策略模式可以使算法可独立于使用它的客户而变化 策略模式变化的是算法
1、许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法
2、需要使用一个算法的不同变体。
3、算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的,与算法相关的数据结构
4、一个类定义了多种行为,并且 这些行为在这个类的操作中以多个形式出现。将相关的条件分支移和它们各自的Strategy类中以代替这些条件语句
*/
// 策略模式
interface CashSuper {
function acceptCash($m);
}
class CashNormal implements CashSuper {
public function acceptCash($m) {
return 'this is cashNormal ' . $m;
}
}
class CashRebate implements CashSuper {
public function acceptCash($m) {
return 'this is cashRebate ' . $m;
}
}
class CashReturn implements CashSuper {
public function acceptCash($m) {
return 'this is cashReturn ' . $m;
}
}
class CashContext {
public $cs;
public function __construct($cs) {
$this->cs = $cs;
}
public function GetResult($money) {
return $this->cs->acceptCash($money);
}
}
$cc = new CashContext(new CashNormal());
echo $cc -> GetResult(100);
php 常用五种模式的更多相关文章
- RabbitMQ详解(三)------RabbitMQ的五种模式
RabbitMQ详解(三)------RabbitMQ的五种模式 1.简单队列(模式) 上一篇文章末尾的实例给出的代码就是简单模式. 一个生产者对应一个消费者!!! pom.xml 必须导入Rab ...
- qemu-kvm磁盘读写的缓冲(cache)的五种模式
qemu-kvm磁盘读写的缓冲(cache)模式一共有五种,分别是writethrough, wirteback, none, unsafe, directsync当你对VM读写磁盘的性能有不同的要求 ...
- RabbitMQ传输原理、五种模式
本文代码基于SpringBoot,文末有代码连接 .首先是一些在Spring Boot的一些配置和概念,然后跟随代码看下五种模式 MQ两种消息传输方式,点对点(代码中的简单传递模式),发布/订阅(代码 ...
- rabbitmq五种模式详解(含实现代码)
一.五种模式详解 1.简单模式(Queue模式) 当生产端发送消息到交换机,交换机根据消息属性发送到队列,消费者监听绑定队列实现消息的接收和消费逻辑编写.简单模式下,强调的一个队列queue只被一个消 ...
- Android常用五种布局
1. FrameLayout(框架布局) 这个布局可以看成是墙脚堆东西,有一个四方的矩形的左上角墙脚,我们放了第一个东西,要再放一个,那就在放在原来放的位置的上面,这样依次的放,会盖住原来的东西.这个 ...
- Rabbitmq的五种模式和案例
消息生产者p将消息放入队列 消费者监听队列,如果队列中有消息,就消费掉,消息被拿走后,自动从队列删除 (缺点:消息可能没有被消费者正确处理,已经消失了,无法恢复) 应用场景:聊天室 1.引入依赖 &l ...
- python实现常用五种排序算法
一.冒泡排序 原理: 比较相邻的元素.如果第一个比第二个大就交换他们两个 每一对相邻元素做同样的工作,直到结尾最后一对 每个元素都重复以上步骤,除了最后一个 第一步: 将乱序中的最大值找出,逐一移到序 ...
- 深度分析Linux下双网卡绑定七种模式 多网卡的7种bond模式原理
http://blog.csdn.net/abc_ii/article/details/9991845多网卡的7种bond模式原理 Linux网卡绑定mode共有七种(~) bond0.bond1.b ...
- 浅谈Linux下的五种I/O模型 两篇别人的博客
http://blog.csdn.net/sinat_34990639/article/details/52778562 http://www.cnblogs.com/chy2055/p/5220 ...
随机推荐
- 学习Visitor Pattern 有感而发!override and overload
通过阅读各位前辈写的博文,像吕震宇,idior,李建忠WebCast等,对Visitor模式有一定的了解,有感而记录下来,以备忘. Visitor Pattern 假设了这样一个场景,在一个类型层次中 ...
- 一个疑难bug的解决过程
一个crontab脚本,下载一个文件并把内容入mysql数据库.具体流程如下: 1, wget一个文件. 2,处理文件生成一个中间文件. 3,将中间文件load入库. 05 10 * * * /hom ...
- ios 好去处
1.王巍的博客(我们都叫它喵神,他很萌哒) 链接:http://onevcat.com/ (难度指数:※※※※※)理由:他的swift的新书讲解的非常好,但不适合入门,进阶的话这是很适合的一本书.其他 ...
- URL与资源
资源推荐 1.HTTP权威指南. <HTTP权威指南>由古尔利所著,<HTTP权威指南>详细解释了HTTP协议,包括HTTP是如何工作的,如何用HTTP来开发基于Web的应用程 ...
- Redis集群方案应该怎么做
方案1:Redis官方集群方案 Redis Cluster Redis Cluster是一种服务器sharding分片技术.Redis Cluster集群如何搭建请参考我的另一篇博文:http://w ...
- C++库研究笔记——生成一组随机数
当试图用 srand(time(0)) rand() 生成一组随机数时发现,生成的数字很多都是「一样」的 经过测试:srand(seed); rand() 生成随机数,当seed一样时,生成的随机数相 ...
- Minimum Size Subarray Sum -- leetcode
题目描写叙述: Given an array of n positive integers and a positive integer s, find the minimal length of a ...
- Node.js&NPM的安装与配置(转)
Node.js安装与配置 Node.js已经诞生两年有余,由于一直处于快速开发中,过去的一些安装配置介绍多数针对0.4.x版本而言的,并非适合最新的0.6.x的版本 情况了,对此,我们将在0.6.x的 ...
- MVC - HtmlHelper类
传统的Html元素不能和服务端数据进行绑定 HtmlHelper类提供了一系列的方法来生成Html元素 并可以实现与数据绑定在一起 然后生成Html Html.BeginForm(actionName ...
- 读写应用程序数据-SQLite3
SQLite3是嵌入到ios中的关系型数据库.对存储大规模的数据非常实用,使得不必将每个对象加到内存中. 支持NULL.INTEGER.REAL(浮点数字).TEXT(字符串和文本).BLOB(二进制 ...