PHP常用的设计模式

2023-05-16

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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PHP常用的设计模式 的相关文章

随机推荐

  • iOS开发,如何让xib关联一个UIView?

    我们创建UIView时 xff0c 默认是没有xib选项的 xff0c 那么如何让xib跟UIView关联 xff1f 还有 xff0c 为什么创建时默认没有xib xff0c 苹果这样做肯定有他自己的想法吧
  • 如何把未知长度的字符串从末尾截掉指定的字串呢?

    如 xff1a 字串 xff1a 沈阳市公安局电话 想截掉尾部的 电话 xff0c 如何实现呢 xff1f
  • android 怎样实现从文本框获得用户名和密码,自动登录网站?

    现有一需求 xff0c 要求从两个文本框输入用户名和密码 xff0c 点击登录后自动登录某网站
  • 字符数组结束符'0'的问题

    字符数组结束符 0 的问题 char str 10 61 I a m h a p p y 如果花括号中提供的字符个数大于数组长度 xff0c 则按语法错误处理 xff1b 若小于数组长度 xff0c 则只将这些字符数组中前面那些元素 xff
  • 切换JDK版本运行java命令时报Error: could not open xxx解决方法

    安装了jdk8和jdk11两个版本 xff0c 并配置好环境变量后 切换jdk8没有问题 xff0c 切换jdk11时输入java version检查版本出现了如下图片问题 xff1b 解决方案1 xff1a 将环境变量path中 JAVA
  • 阿里云服务器ubuntu18.04安装可视化界面

    这里写目录标题 一 远程连接ubuntu二 安装可视化界面三 安装过程中的问题 一 远程连接ubuntu 输入root密码即可 xff08 这个为实例密码 xff09 二 安装可视化界面 依次输入以下shell命令 apt span cla
  • 奇偶检验等N、O、E、M、S 五种串口检验位类型

    一 检验位 在串行通讯所发送数据的最后一位 xff0c 用来粗略的检验数据在传输过程中是否有出错 二 检验位的五种类型 1 N xff08 None 没有 xff09 无校验 不加校验位 xff0c 可以少传输一位数据 2 O xff08
  • Onvif登录海康、大华摄像机(IPC)提示权鉴失败的问题解决

    最近用我们的Onvif设备发现客户端测试 xff0c 发现连接某些摄像机Onvif获取不到设备信息 xff0c 提示401权鉴失败 确认用户名和密码都没错的情况下 xff0c 都还是失败 xff0c 软件提示信息截图如下 xff1a 我们测
  • 反解析Android APK

    重命名APK为zip 并解压到当前文件中 下载dex解析工具dex2jar link https github com pxb1988 dex2jar releases tag v2 2 SNAPSHOT 2021 10 31 解析文件命令
  • 大数加法越界处理

    大数越界处理 当数据很大时 xff0c 求中点的方法 i 43 j 2的结果有可能会超出 int 类型的取值范围 在此情况下 xff0c 我们需要换一种计算中点的写法 i 43 j 有可能超出 int 的取值范围 int m 61 i 43
  • idea使用断言

    测试程序 public class TestAssert public static void main String args String s1 61 null assert s1 61 null 默认assert不起作用 需开启 ve
  • 2018年面试总结 -- 多线程很重要,多总结很重要

    2018年面试总结 先后面试了Android Linux C C 43 43 QT 得到的结论有以一下几条 xff1a 1 多线程作为一个高级话题太重要了 几乎每种开发环境下都会问到 xff0c 无论是Android还是QT xff1b 2
  • 平常使用的小问题【Windows11开启不了热点,开启热点后连不上去】

    故障现象 xff1a xff08 1 xff09 连接设备一直显示obtaining ip address xff08 2 xff09 电脑没有显示连接的设备 解决措施 xff1a xff08 1 xff09 先转到设置 xff08 2 x
  • IOException: No such file or directory 问题解决

    文章目录 问题描述 xff1a 注册权限动态申请权限总结 xff1a 问题描述 xff1a Android开发 xff0c 在访问文件夹创建文件的时候 xff0c 报错IOException No such file or director
  • 2020(春)工程伦理MOOC期末考试答案

    单选题 多选题 判断题
  • Git中Fork使用

    GitLab或者GitHub中的Fork可以理解为一个物理副本 xff0c 用来管理代码的一种手段 在参与开源项目代码贡献时 xff0c 通常不会直接获得源代码仓库的Developer权限 这点和一般公司开发不太一样 xff0c 公司一般都
  • 在OK6410上运行QT程序找不到libQtGui.so.4的解决

    想在OK6410上运行自己经过交叉编译的QT程序 xff0c OK6410上烧写的是光盘所带的Linux系统 xff0c 运行程序时出现以下现象 xff1a qt server error while loading shared libr
  • Docker的安装

    这篇文章原文是我2016年10月份写的 xff0c 当时在研究docker xff0c 上周六不经意翻了出来 xff0c 由于3月换工作 xff0c 新环境比较忙 xff0c 没时间写些东西 xff0c 所以先把之前写的东西放一下 xff0
  • CRAZEPONY飞控学习(一)

    在不久前曾研究过最近最为流行的开源飞控Pixhawk的源代码 xff0c 但是由于在这之前没有接触过操作系统这个概念 xff0c 在不知道代码执行流程的情况下看了几个星期的时间 xff0c 脑子里还是一团乱 xff0c 所以决定还是从裸机开
  • PHP常用的设计模式

    php常用的设计模式 xff1a 1 单例模式 xff08 构造方法私有化 xff0c 对外提供实例化对象的静态调用方法 xff09 class Site span class token punctuation span public s