php常用的设计模式:
1、单例模式(构造方法私有化,对外提供实例化对象的静态调用方法)
class Site
{
public $siteName;
public static $instance = null;
private function __construct($siteName)
{
$this->siteName = $siteName;
}
// 实例化本类
public static function getInstance($siteName='gongxulei.cn')
{
// 判断当前的静态属性是不是当前类的实例,如果不是则创建它
if(!self::$instance instanceof self){
self::$instance = new self($siteName);
}
return self::$instance;
}
}
2、工厂模式(创建单例模式的实例)
class Factory
{
public static function create()
{
return Site::getInstance('gongxulei.cn');
}
}
3、注册树模式(用于存储对象的对象池。get、set、destroy对象)
/**
* Class Register
* 1. 注册:set(),将对象添加到对象池中
* 2. 获取:get(),从对象池中获取对象
* 3. 注销:_unset(),从对象池中释放对象
*/
class Register
{
// 创建对象池:数组
protected static $objects = [];
public static function set($alias,$object){
self::$objects[$alias] = $object;
}
public static function get($alias){
return self::$objects[$alias];
}
public static function _unset($alias){
unset(self::$objects[$alias]);
}
}
在PHP框架laravel、thinkphp中使用的container容器技术就是使用了以上三种模式,通过以上三种模式可以实现对已实例化的对象的复用,并防止重复的实例化。
4、适配器模式:将各种截然不同的函数接口封装成统一的API。
如:对于不同类型的数据库,框架一般都会封装成统一调用的api。
<?php
interface Cache
{
function connect($host, $user, $passwd, $dbname);
function set($key, $value);
function get($key);
}
class redisCache implements Cache
{
public function connect($host, $user, $passwd, $dbname)
{
}
//设置缓存
public function set()
{
}
//获取缓存
public function get()
{
}
}
class memCache implements Cache
{
public function connect($host, $user, $passwd, $dbname)
{
}
//设置缓存
public function set()
{
}
//获取缓存
public function get()
{
}
}
?>
5、策略模式:将一组特定的行为和算法封装成类,以适应某些特定的上下文环境。
例如:对于传统编程中,如果apple跟pear都有相同的价格列表、价格详情两个页面,那么会在控制器中进行类型判断,然后获取价格apple的列表,pear的价格列表,随着类型增多价格列表方法中增加的逻辑代码就会越来越多,代码的耦合度也会越高。
如果使用策略模式进行编程,控制器中只需要判断是那种类型然后实例化不同的策略类,如果新增一个类型,那只需要新增一个策略即可,大大降低代码的耦合度,方便后期维护
<?php
# 行情通策略模式处理价格相关页面
namespace app\test\strategy;
interface PriceStrategy
{
/**
* 价格列表
* @return mixed
*/
public function priceList();
/**
* 价格详情
* @return mixed
*/
public function priceDetail();
}
<?php
namespace app\test\classfiy;
use app\test\strategy\PriceStrategy;
class Apple implements PriceStrategy
{
/**
* 价格列表
* @return mixed
*/
public function priceList($param = [])
{
return "这是apple的价格列表";
}
/**
* 价格详情
* @return mixed
*/
public function priceDetail()
{
return "这是apple的价格详情";
}
}
<?php
namespace app\test\classfiy;
use app\test\strategy\PriceStrategy;
class Pear implements PriceStrategy
{
/**
* 价格列表
* @return mixed
*/
public function priceList($param = [])
{
return "这是Pear的价格列表";
}
/**
* 价格详情
* @return mixed
*/
public function priceDetail()
{
return "这是Pear的价格详情";
}
}
<?php
namespace app\test\controller;
use app\test\classfiy\Apple;
use app\test\classfiy\Pear;
use think\Request;
class PriceController
{
/**
* 价格列表
* @access public
* @param mixed $field 字段描述
* @return mixed
**/
public function priceListAction(Request $request)
{
$param = $request->param();
$type = $param['type'] ?: 'apple';
switch ($type) {
case 'apple':
$strategy = new Apple();
break;
case 'pear':
$strategy = new Pear();
break;
default:
$strategy = new Apple();
break;
}
$info = $strategy->priceList($param);
echo $info;
}
/**
* 价格详情
* @access public
* @param mixed $field 字段描述
* @return mixed
**/
public function priceDetailAction(Request $request)
{
$param = $request->param();
$type = $param['type'] ?: 'apple';
switch ($type) {
case 'apple':
$strategy = new Apple();
break;
case 'pear':
$strategy = new Pear();
break;
default:
$strategy = new Apple();
break;
}
$info = $strategy->priceDetail($param);
echo $info;
}
}
6、观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
//观察者模式:定义事件类
class Event
{
private $observerList = [];
//新增监听
public function addObserver( $alias = "", Observer $observer)
{
if (empty($alias)) {
$alias = get_class($observer);
}
$this->observerList[$alias] = $observer;
}
//调用通知
private function notify($alias, $param = [])
{
foreach ($this->observerList as $event => $observer)
{
if ($event == $alias) {
$res = $observer->handle($param);
}
}
return $res;
}
//事件触发器
public function trigger($alias, $param = [])
{
return $this->notify($alias, $param);
}
}
//定义观察接口
interface Observer
{
public function handle($param);
}
class abserverOne implements Observer
{
public function handle($param)
{
// TODO: Implement handle() method.
return "abserverOne收到通知,去更新了价格\r\n";
}
}
class abserverTwo implements Observer
{
public function handle($param)
{
// TODO: Implement handle() method.
return "abserverTwo收到通知,去新增了redis队列数据";
}
}
$event = new Event();
//添加观察
$event->addObserver('', (new abserverOne()));
$event->addObserver('', (new abserverTwo()));
//触发事件
echo $event->trigger('abserverOne');
echo $event->trigger('abserverTwo');
// 输出结果如下:
// abserverOne收到通知,去更新了价格
// abserverTwo收到通知,去新增了redis队列数据
7、装饰器模式:装饰器模式可以动态的添加修改类的功能,抽象类提供了一项功能,如果要在修改并添加额外的功能,传统的编程是写一个子类去继承它,并重新实现类的方法,使用装饰器模式,仅需在运行时添加一个装饰器对象即可实现,可以实现最大的灵活性
<?php
/*
* 装饰器抽象类
*/
abstract class Beverage
{
public $_name;
abstract public function Cost();
}
// 被装饰者
class Coffee extends Beverage
{
public function __construct()
{
$this->_name = 'Coffee';
}
public function Cost()
{
return 1.00;
}
}
// 以下三个类是装饰者相关类
//装饰类
class CondimentDecorator extends Beverage
{
public function __construct()
{
$this->_name = 'Condiment';
}
public function Cost()
{
return 0.1;
}
}
//装饰器:配料:牛奶
class Milk extends CondimentDecorator
{
public $_beverage;
public function __construct($beverage)
{
if ($beverage instanceof Beverage) {
$this->_name = $beverage->_name . '+Milk';
$this->_beverage = $beverage;
} else {
exit('Failure');
}
}
public function Cost()
{
return $this->_beverage->Cost() + 0.5;
}
}
//装饰器:配料:糖
class Sugar extends CondimentDecorator
{
public $_beverage;
public function __construct($beverage)
{
if ($beverage instanceof Beverage) {
$this->_name = $beverage->_name . '+Sugar';
$this->_beverage = $beverage;
} else {
exit('Failure');
}
}
public function Cost()
{
return $this->_beverage->Cost() + 0.2;
}
}
//1、获取coffee
$coffee = new Coffee();
//2.加点牛奶计算成本
$milk = new Milk($coffee);
echo $milk->_name;
echo $milk->Cost();
echo "\r\n";
//3.加点糖计算成本
$sugar = new Sugar($coffee);
echo $sugar->_name;
echo $sugar->Cost();
//输出结果
// Coffee+Milk1.5
// Coffee+Sugar1.2