php常用设计模式
工厂模式
工厂模式是最常用也是最简单的一种设计模式了,不需要用关键字new就可以获取实例,减少代码耦合,提高代码的可扩展性。
例如你想修改某个实例化的类名,不需要去每个实例化的地方改,可以直接在工厂模型修改即可。
简单的例子:
class Factory
{
public static function get Instance (string $newclass)
{
return new $class;
}
}
$object = Factory::getInstance('class1')
单例模式
单例模式,最大的特点是,在整个应用进程中,只会存在一个该类的实例,一旦创建,就会一直保存在内存中。
一般具备以下几个特征,1、私有的静态变量,用来存放实例,2、私有的构造和克隆方法,3、公有的静态方法对外界提供获取实例入口,俗称三私一公。
最常用的场景应该是数据库模型了,使用单例模式,只需连接一次数据库,节约资源。
简单的例子:
class SingleCase
{
private static $_instance;
private function __construct(){}
private function __clone(){}
public static function getInstance()
{
return self::$_instance = new self();
}
}
$instance = SingleCase::getInstance();
观察者模式
当一个对象状态发生变化时,依赖他的对象全部会收到通知,并自动更新。是一种低耦合,非入侵式的通知和更新机制。
一个事件发生后,要执行一连串更新操作,传统的编程方式,就是在事件的代码之后直接加入处理的逻辑。当更新的逻辑越来越多的时候,代码会变得难以维护,观察者模式解决了这个问题。
简单的例子
//主题接口
interface Subject
{
public function register(Observer $observer);
public function notify();
}
// 观察者接口
interface Observer
{
public function watch();
}
//主题
class Action implements Subject
{
public $_observers = [];
public function register(Observer $observer)
{
$this->_observers[] = $observer;
}
public function notify()
{
foreach ($this->_observers as $o) {
$o->watch();
}
}
}
//观察者
class Cat implements Observer
{
public function watch ()
{
echo 'cat watch';
}
}
class Dog implements Observer
{
public function watch()
{
echo 'dog watch';
}
}
class People implements Observer
{
public function watch()
{
echo 'people watch';
}
}
//注册动作
$act = new Action();
$act->register(new Cat);
$act->register(new Dog);
$act->register(new People);
//调用实例
$act->notify();
#注册模式
注册模式,解决了全局共享和交换对象问题。已经创建好的对象,挂在到某个全局可以使用的数组上,在需要使用的时候,直接从该数组上获取即可。将对象注册到全局的树上。任何地方直接去访问。
代码示例
class Register
{
protected static $objects;
function set($alias,$object)//将对象注册到全局的树上
{
self::$objects[$alias]=$object;//将对象放到树上
}
static function get($name){
return self::$objects[$name];//获取某个注册到树上的对象
}
function _unset($alias)
{
unset(self::$objects[$alias]);//移除某个注册到树上的对象。
}
}
适配器模式
将各种不同的函数接口封装成统一的api
例如php的数据库操作有mysql、mysqli、pdo三种,可以使用适配器统一成一个对外接口
首先定义个接口,有几种不同的情况,就写几个类实现该接口。将完成相似功能的函数,统一成一致的方法。
/**
* 目标角色
*/
interface Target {
/**
* 源类也有的方法1
*/
public function sampleMethod1();
/**
* 源类没有的方法2
*/
public function sampleMethod2();
}
/**
* 源角色
*/
class Adaptee {
/**
* 源类含有的方法
*/
public function sampleMethod1() {
echo 'Adaptee sampleMethod1 <br />';
}
}
/**
* 类适配器角色
*/
class Adapter extends Adaptee implements Target {
/**
* 源类中没有sampleMethod2方法,在此补充
*/
public function sampleMethod2() {
echo 'Adapter sampleMethod2 <br />';
}
}
class Client {
/**
* Main program.
*/
public static function main() {
$adapter = new Adapter();
$adapter->sampleMethod1();
$adapter->sampleMethod2();
}
}