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 ...
随机推荐
- Open Dynamics Engine for Linux 安装笔记
下载 在Bitbucket上可以下载到最新的版本(截止目前为0.14版) 或者直接用wget下载 wget "https://bitbucket.org/odedevs/ode/downlo ...
- Oracle Enterprise Linux 64-bit下安装apache-tomcat-7.0.53步骤
測试环境:VMware Workstation v9.0.2软件中安装好Oracle Enterprise Linux 5.8 64-bit虚拟机 安装软件:jdk-7u40-linux-x64.rp ...
- android应用程序的优先级
andorid系统为保障应用程序运行的流畅性,当内存资源比较匮乏的时候会杀死那些优先级比较低的进程 android进程的优先级如下图: 1.活动进程: 是指那些正在与用户进行交互的应用程序进程,这种组 ...
- QT显示输出及其桌面
/* 应用程序桌面 */ QDesktopWidget* desktop = QApplication::desktop(); /* 指定显示器的屏幕尺寸(1024 * 768) */ QRect ...
- 69 Spring Interview Questions and Answers – The ULTIMATE List--reference
This is a summary of some of the most important questions concerning the Spring Framework, that you ...
- Java synchronized 总结
在Java开发的时候经常会用到关键字synchronized来对代码进行同步,在使用的过程中,对于synchronized确不是很熟悉,最近在看Spring源码时,发现有不少地方都用到同步,因此,趁此 ...
- PowerDesigner使用详解
PowerDesign高级应用编写相关的VBS脚本在PowerDesign里自定义一些命令与操作等,具体的可以参考C:\Program Files\Sybase\PowerDesigner 9\VB ...
- 提升资源利用率的MapReduce框架
Hadoop系统提供了MapReduce计算框架的开源实现,像Yahoo!.Facebook.淘宝.中移动.百度.腾讯等公司都在借助 Hadoop进行海量数据处理.Hadoop系统性能不仅取决于任务调 ...
- 在AngularJS的controller外部直接获取$scope
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/SJQ. http://www.cnblogs.com/shijiaqi1066/p/5560843.html ...
- nofollow标签如何使用
“nofollow”的意思是不传递权重,向网站站长提供了一种方式,即告诉搜索引擎“不要追踪此网页上的链接”或“不要追踪此特定链接”. nofllow的形式 1.<meta name=" ...