PHP模式设计之单例模式、工厂模式、注册树模式、适配器模式、观察者模式
php模式设计之单例模式
什么是单例模式?
单例模式是指在整个应用中只有一个实例对象的设计模式
为什么要用单例模式?
php经常要链接数据库,如果在一个项目中频繁建立连接数据库,会造成服务器资源的很大浪费,在团队合作项目中,也能够避免不同的程序员实例自己的对象,造成人为的系统消耗。
单例模式的三大原则
1.构造函数需要标记为非public(防止外部使用new操作符创建对象),单例类不能在其他类中实例化,只能被其自身实例化
2.拥有一个保存类的实例的静态成员变量$_instance
3.拥有一个可以访问这个实例的公共静态方法
示例代码
<?php
/**
* php设计模式之单例模式
*/
class Db
{
static private $_instance; final protected function __construct()
{
# code...
} public static function getInstance()
{
if (!self::$_instance instanceof self) {
self::$_instance=new Db();
}
return self::$_instance;
} public function connect()
{
//链接数据库
}
}
?>
php模式设计之工厂模式
什么是工厂模式?
工厂模式是指根据不同的参数生成不同的类实例。
为什么要用工厂模式?
减少代码进行复制粘帖,耦合关系重,牵一发动其他部分代码,比如在项目中很多地方实例化某个类,现在突然发现类名不合适或者类中需要添加构造函数参数,难不成需要一个个改?典型的例子就是连接数据库,php中连接数据库有好几种方法,mysql扩展,mysqli扩展等,这个时候就可以用到工厂模式。
示例代码
<?php
/**
* php设计模式之工厂模式
*/
class Db
{
public static function factory($param){
switch ($param) {
case 'mysql':
return new Class1();
break; case 'mysqli':
return new Class2();
break; case 'mssql':
return new Class3();
break;
}
}
} interface Connect
{
public function fun1($param);
} class Class1 implements Connect
{
public function fun1($param){
//具体实现
}
} class Class2 implements Connect
{
public function fun1($param){
//具体实现
}
} class Class3 implements Connect
{
public function fun1($param){
//具体实现
}
}
?>
php模式设计之注册树模式
什么是注册树模式?
注册树模式通过将对象实例注册到全局对象树上,需要的时候将对象从全局对象树上取下来
为什么要用工厂模式?
前面讲到的单例模式解决了在整个项目中创建唯一对象的问题,工厂模式解决了不通过new解决实例对象的问题,考虑的是项目扩展与维护。总得来说单例模式和工厂模式可以产生更加合理的对象,那么怎么方便统筹调用这些对象呢,这时候就用到了注册树模式,不管你是单例模式,工厂模式还是二者结合生成的对象,都统统给我注册到树上,用某个对象的时候,直接从树上取下来就好。
示例代码
<?php
/**
* 单例模式
*/
class Signal
{
static private $_instance;
final protected function __construct()
{
# code...
}
public static function getInstance()
{
if (!self::$_instance instanceof self) {
self::$_instance=new Signal();
}
return self::$_instance;
}
public function connect()
{
//链接数据库
}
}
/**
* 工厂模式
*/
class Db
{
public static function factory($param='')
{
switch ($param) {
case 'mysql':
return new Class1();
break;
case 'mysqli':
return new Class2();
break;
case 'mssql':
return new Class3();
break;
default:
return Signal::getInstance();
}
}
}
interface Connect
{
public function fun1($param);
}
class Class1 implements Connect
{
public function fun1($param)
{
//具体实现
}
}
class Class2 implements Connect
{
public function fun1($param)
{
//具体实现
}
}
class Class3 implements Connect
{
public function fun1($param)
{
//具体实现
}
}
/**
*注册树模式
*/
class Register
{
static protected $objects;
/**
* 插入对象实例
* @param string $alias
* @param object $object 对象实例
*/
public static function set($alias,$object)
{
self::$objects[$alias]=$object;
}
/**
* 撤销对象实例
* @param string $alias
*/
public static function _unset($alias)
{
unset(self::$objects[$alias]);
}
/**
* 获取对象实例
* @param string $alias
* return object
*/
public static function get($alias)
{
return self::$objects[$alias];
}
}
Register::set('signal',Db::factory());
$signal=Register::get('signal');
$signal->connect();
?>
php模式设计之适配器模式
什么是适配器模式?
把对某些相似的类的操作转化为一个统一的"接口"--适配器,或者比喻为某个"界面",统一或者屏幕那些类的细节.适配器模式还构造了一种"机制",使"适配"的类很容易增减,而不用修改与之交互的代码,符合减少代码间的耦合。
为什么要用适配器模式?
主要应用于"希望复用一些现成的类,但是接口又与复用环境不一致"的情况
示例代码
1.源(Adaptee)角色:Toy系列类保持不变
<?php
abstract class Toy
{
public abstract function openMouth(); public abstract function closeMouth();
} class Dog extends Toy
{
public function openMouth()
{
echo "Dog open Mouth\n";
} public function closeMouth()
{
echo "Dog close Mouth\n";
}
} class Cat extends Toy
{
public function openMouth()
{
echo "Cat open Mouth\n";
} public function closeMouth()
{
echo "Cat close Mouth\n";
}
}
?>
2.目标(Target)角色接口
<?php
//目标角色:红枣遥控公司
interface RedTarget
{
public function doMouthOpen(); public function doMouthClose();
} //目标角色:绿枣遥控公司及
interface GreenTarget
{
public function operateMouth($type = 0);
}
?>
3.适配器角色代码实现
//类适配器角色:红枣遥控公司
class RedAdapter implements RedTarget
{
private $adaptee; function __construct(Toy $adaptee)
{
$this->adaptee = $adaptee;
} //委派调用Adaptee的sampleMethod1方法
public function doMouthOpen()
{
$this->adaptee->openMouth();
} public function doMouthClose()
{
$this->adaptee->closeMouth();
}
} //类适配器角色:绿枣遥控公司
class GreenAdapter implements GreenTarget
{
private $adaptee; function __construct(Toy $adaptee)
{
$this->adaptee = $adaptee;
} //委派调用Adaptee:GreenTarget的operateMouth方法
public function operateMouth($type = 0)
{
if ($type) {
$this->adaptee->openMouth();
} else {
$this->adaptee->closeMouth();
}
}
}
4.测试用例
<?php
class testDriver
{
public function run()
{
//实例化一只狗玩具
$adaptee_dog = new Dog();
echo "给狗套上红枣适配器\n";
$adapter_red = new RedAdapter($adaptee_dog);
//张嘴
$adapter_red->doMouthOpen();
//闭嘴
$adapter_red->doMouthClose();
echo "给狗套上绿枣适配器\n";
$adapter_green = new GreenAdapter($adaptee_dog);
//张嘴
$adapter_green->operateMouth(1);
//闭嘴
$adapter_green->operateMouth(0);
}
} $test = new testDriver();
$test->run();
?>
php模式设计之观察者模式
什么是观察者模式?
从面向过程的角度来看,首先是观察者向主题注册,注册完之后,主题再通知观察者做出相应的操作,整个事情就完了
从面向对象的角度来看,主题提供注册和通知的接口,观察者提供自身操作的接口。(这些观察者拥有一个同一个接口。)观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者。耦合度相当之低
为什么要用观察者模式?
观察者模式更多体现了两个独立的类利用接口完成一件本应该很复杂的事情。不利用主题类的话,我们还需要不断循环创建实例,执行操作。而现在只需要创建实例就好,执行操作的事儿只需要调用一次通知的方法就好啦
示例代码
<?php
// 主题接口
interface Subject{
public function register(Observer $observer);
public function notify();
}
// 观察者接口
interface Observer{
public function watch();
}
// 主题
class Action implements Subject{
public $_observers=array();
public function register(Observer $observer){
$this->_observers[]=$observer;
} public function notify(){
foreach ($this->_observers as $observer) {
$observer->watch();
} }
} // 观察者
class Cat implements Observer{
public function watch(){
echo "Cat watches TV<hr/>";
}
}
class Dog implements Observer{
public function watch(){
echo "Dog watches TV<hr/>";
}
}
class People implements Observer{
public function watch(){
echo "People watches TV<hr/>";
}
} // 应用实例
$action=new Action();
$action->register(new Cat());
$action->register(new People());
$action->register(new Dog());
$action->notify();
?>
PHP模式设计之单例模式、工厂模式、注册树模式、适配器模式、观察者模式的更多相关文章
- php模式设计之 注册树模式
在前两篇单例模式和工厂模式后,终于迎来了最后一个基础的设计模式--注册树模式. 什么是注册树模式? 注册树模式当然也叫注册模式,注册器模式.之所以我在这里矫情一下它的名称,是因为我感觉注册树这个名称更 ...
- php模式设计之 单例模式
模式设计是什么?初学者一开始会被这高大上的名称给唬住.而对于有丰富编程经验的老鸟来说,模式设计又是无处不在.很多接触的框架就是基于各种模式设计形成的. 简单说,在写代码的过程中一开始往往接触的是面向过 ...
- PHP设计模式笔记三:三种基本设计模式(工厂模式、单例模式、注册树模式) -- Rango韩老师 http://www.imooc.com/learn/236
一.工厂设计模式 index.php $db = IMooc\Factory::createDatabase(); 使用工厂类的静态方法直接创建一个dababase对象,当类名发生修改时,在工厂里修改 ...
- php基础设计模式 注册树模式、工厂模式、单列模式
废话不多说了,先给大家介绍注册树模式然后介绍工厂模式最后给大家介绍单列模式,本文写的很详细,一起来学习吧. php注册树模式 什么是注册树模式? 注册树模式当然也叫注册模式,注册器模式.之所以我在这里 ...
- Yii2设计模式——注册树模式
应用举例 在Yii.php中: <?php class ServiceLocator extends Component { //保存实例化的对象,每个对象都是单例,且有唯一string类型的I ...
- 2018/04/24 PHP 设计模式之注册树模式
之前学习了工厂模式和单例模式,明白了他们的意义. 但是我们在之后的使用中会发现一个问题,在新建一个实例的时候还是需要调用一个单例或者工厂,之后还是造成了代码和耦合和不好处理. 下面开始说一下: -- ...
- php设计模式之注册树模式
什么是注册树模式?[全局共享和交换对象] 注册树模式当然也叫注册模式,注册器模式.注册树模式通过将对象实例注册到一棵全局的对象树上,需要的时候从对象树上采摘的模式设计方法. 这让我想起了小时候买糖 ...
- PHP设计模式_注册树模式
通过注册树模式可以更加简单快捷的获取对象,在某个地方实例化了一个对象,可以将这个对象“保存”起来(放入可以全局使用的数组里),用的时候只需要提供 保存对象的时候 的那个标识即可,解决全局共享和交换对象 ...
- php设计模式-注册树模式
php注册树模式 1.什么是注册树模式? 注册树模式通过将对象实例注册到全局对象树上,需要的时候将对象从全局对象树上取下来,就像小时候买糖葫芦一样,卖糖葫芦的将糖葫芦插在一个大的杆子上,人们买的时候就 ...
随机推荐
- IDEA的配置
一.使用配置 转自:http://blog.csdn.net/qq_27093465/article/details/52918873 setting: 设置外观和字体: 设置编辑器快捷键: 自动 ...
- PHP/JAVA 杂谈 一(php 槽点)
[本文为个人意见,不喜就喷吧!] 最近,同事问到我,『那时候为什么从PHP转成Java?』,我想了很久,且撇开主观上的原因,当初业务重构使用java确实有很多可以说道的地方. 槽点1:哪有最好的语言, ...
- Python的Argparse模块是什么?(未完)
近日在阅读代码的过程中遇到了Argparse模块,记得前段时间已经看了,可是过了两周现在又忘了, 看来写代码一定要钻研到底搞清楚其中原委才行,本文主要参考Python3.6系列官方文档 ...
- Django数据模型——数据库字段类型
字段 一个模型最重要也是唯一必需的部分,是它定义的数据库字段 字段名称限制 1.字段名不能是python保留字,这样会导致python语法错误 2.字段不能包含连续一个以上的下划线,这样会和Djang ...
- python web开发-flask中日志的使用
Flask使用日志记录的方式: 初始化flask应用实例 在flask中使用logger,需要初始化一个flask的应用 app = Flask(__name__) 2. 调用logger 直接调用l ...
- angularjs上传图片和文件
很简单: $scope.upload = function() { var f = $scope.myFile; var fd = new FormData(); var img = document ...
- 一篇关于Maven项目的jar包Shell启动脚本
使用Maven作为项目jar包依赖的管理,常常会遇到命令行启动,笔者也是哥菜鸟,在做微服务,以及服务器端开发的过程中,常常会遇到项目的启动需要使用main方法,笔者潜心的研究了很多博客,发现大多写的都 ...
- 笔记:Maven 私服 Nexus 权限控制
Nexus 用户 Nexus 预定义了三个用户,这三个用户对应了三个权限级别: admin:该用户拥有对Nexus服务的完全控制,默认密码为 admin123,以下为admin用户的角色树 deplo ...
- 你不知道的Google控制台
1.页面可编辑 document.body.contentEditable=true 2.console.table() 3.console.dir 4.clear() 清空控制台 5.sources ...
- window平台写的shell脚步在Linux不识别
---恢复内容开始--- 出现的问题是 写的shell脚步在Linux执行的时候不被识别 解决方案: 1.确保用户对文件有读写及执行权限 oracle@linux-106:~/RMAN/bin> ...