zoukankan      html  css  js  c++  java
  • PHP 设计模式

    单例模式

    单个实例,实例就是对象。限制类只能有一个对象。

    class Danli{
        // 私有化构造方法,禁止外部实例化对象
        private function __construct(){}
        // 私有化属性
        private static $_instance;
        // 禁止外部克隆
        private function __clone(){}
    
        // 实例化类
        public static function getInstance(){
            // 判断类是否存在
            if(!isset(static::_instance)){
                // 不存在,实例化,并存储在属性上
                static::_instance=new static(); // new Danli()  new self()
             }
            return static::_instance; 
        }
    }
    // 调用
    $danli=Danli::getInstance();

    三私一公,三个私有属性,一个公共方法。

    单例的另一种形式

    判断是否已经实例化,放在类外判断。

    class Danli{
        // 业务代码
    }
    
    // 实例化类
    function getInstance(){
        static $_instance;
        // 判断类是否存在
        if(!isset($_instance)){
            // 不存在,实例化
            $_instance=new Danli()
         }
        return $_instance; 
    }
    
    // 调用
    $danli=getInstance();

    优势:灵活,同时适合多个类,不需要改类本身的结构。

    劣势:没有从根本上解决单例的问题。

    多个类的应用:

    class Danli{
        // 业务代码
    }
    
    // 实例化类
    function getInstance($class_name){
        static $_instance_list=array();
        // 判断类是否存在
        if(!isset($_instance_list[$class_name])){
            // 不存在,实例化
            $_instance_list[$class_name]=new $class_name();// 可变标识符,可变类语法
         }
        return $_instance_list[$class_name]; 
    }
    
    // 调用
    $danli=getInstance('Dysql');

    简单工厂模式

    class Factory{
        // 实例化类
        public static function getInstance($class_name){
         // 静态局部变量,函数调用后不会消失,下次调用还在
    static $_instance_list=array(); // 判断类是否存在 if(!isset($_instance_list[$class_name])){ // 不存在,实例化 $_instance_list[$class_name]=new $class_name();// 可变标识符,可变类语法 } return $_instance_list[$class_name]; } } class One{};
    // 利用工厂得到对象
    $factory=Factory::getInstance('One');

    当直接new 无法满足业务需要,需要一些判断时用到工厂类。工厂类里面的方法都是静态方法,因为工厂类一般不需要实例化自身。

    观察者模式

    // 观察者模式,实现系统的方法
    class User implements SplSubject{
        // 登录次数
        public $lognum;
        // 定义存储对象的属性
        protected $observers = null;
        
        public function __construct(){
            $this->lognum=rand(1,10);
            // 存储对象的类赋值给 observers 属性
            $this->observers=new SplObjectStorage();
        }
        
        public function login(){
            // 通知观察者
            $this->notify();
        }
        
        // 添加观察对象
        public function attach(SplSubject $observer){
            $this->observers->attach($observer);
        }
        
        // 删除观察对象
        public function detach(SplSubject $observer){
            $this->observers->detach($observer);
        }
        
        // 通知对象,指针回到头部
        public function notify(){
            $this->observers->rewind();
            // 如果存储对象中还有数据
            while($this->observers->valid()){
                $observer=$this->observers->current();// 当前值
                // 通知方法
                $observer->update($this);
                $this->observers->next();// 指针下移一个
            }
        }
    }
    
    // 安全登录模块,SplObserver接口用于一起 SplSubject实现Observer设计模式。
    class Secrity implements SplSubject{
        // 通知对象
        public function update(SplSubject $subject){
            if($subject->lognum <3){
                echo "第".$subject->lognum."次安全登录";
            }else{
                echo "第".$subject->lognum."次异常登录";
            }
        }
    }
    
    // 调用
    $user=new User();
    $user->attach(new Secrity());
    $user->login();

    策略模式

    // 计算器
    interface Math{
        public function calc($num,$num2);
    }
    
    // 加法运算
    class MathAdd implements Math{
        public function calc($num,$num2){
            return $num+$num2;
        }
    }
    
    // 减法运算
    class MathSub implements Math{
        public function calc($num,$num2){
            return $num+$num2;
        }
    }
    
    // 调用计算--策略模式,没有直接new MathAdd,而是通过CMath的一个属性调用,此处高聚合
    class CMath{
        private $calc;
        // 实例化计算器
        public function __construct($type){
            $calc_name='Math'.$type;
            $this->calc=new $calc_name();
        }
        // 执行计算
        public function execCalc($num,$num2){
            return $this->calc->calc($num,$num2);
        }
    }
    
    //调用
    $cmath=new CMath('Add');
    echo $cmath->execCalc(1,2);

    策略模式是要调用的类通过另一个类的属性调用,工厂模式是创建出来直接调用。

    装饰器模式

    // 基本的文章内容处理
    class BaseArt{
        protected $content; // 存放文章内容
        protected $art; // 存储文章对象
            // 传入文章内容
        public function __construct($content){
            $this->content=$content;
        }
        // 直接返回文章内容
        public function decorator(){
            return $this->coutent;
        }
    }
    
    // 添加摘要功能
    class KeyArt extends BaseArt{
        // 基本数据传过来
        public function __construct(BaseArt $art){
            $this->art=$art;
            $this->decorator();
        }
        
        public function decorator(){
            // 处理原来的数据
            return $this->countent='添加摘要'.$this->art->decorator();
        }
    }
    
    // 添加SEO功能
    class SeoArt extends BaseArt{
        // 基本数据传过来
        public function __construct(BaseArt $art){
            $this->art=$art;
            $this->decorator();
        }
        
        public function decorator(){
            // 处理原来的数据
            return $this->countent='添加SEO'.$this->art->decorator();
        }
    }
    
    // 调用
    $article=new SeoArt(new KeyArt(new BaseArt('文章内容')));
    echo $article;

    适配器模式

    就是一种转换处理方式

    // 输出格式为数组
    class Dianya{
        public function show(){
            return ['fute'=>2,'dianya'=>10];
        }
    }
    
    // 需要返回 json 数据
    class ZDianya extends Dianya{
        public function show(){
            $data=parent::show();
            return json_encode($data);
        }
    }
    
    //获取数组类型数据
    $dianya=new Dianya();
    echo $dianya->show();
    
    // 通过适配器调用
    $zdianya=new ZDianya();
    echo $zdianya->show();

    桥接模式

    对象与对象建立连接的一种方式。

    // 发送信息
    abstract class Msg{
        protected $send;
        public function __construct($send){
            $this->send=$send; // 这个接收到的发送短信、邮件的类对象
        }
        // 获取信息内容
        abstract public function info($con);
        // 执行发送
        public function send($to,$con){
            $cont=$this->info($con);    // 普通 还是 加急 的信息
            $this->send->send($to,$con);// 短信、邮件的类对象执行发送方法
        }
    }
    
    // 发送短信
    class Sms{
        public function send($to,$con){
            echo  '发送短信给'.$to.'内容'.$con;
        }
    }
    
    // 发送邮件
    class Mail{
        public function send($to,$con){
            echo  '发送邮件给'.$to.'内容'.$con;
        }
    }
    
    // 普通
    class Ordinary extends Msg{
        public function info($con){
            echo '普通';
        }
    }
    
    // 加急
    class Waring extends Msg{
        public function info($con){
            echo '加急';
        }
    }
    
    // 调用
    $ordinary=new Ordinary(new Sms());
    $ordinary->send('11223123','测试');
  • 相关阅读:
    python并发之concurrent.futures
    全局解释器锁--GIL
    ASP 注释
    ASPxGridView 下拉框不让输入
    leftjoin及多个leftjoin执行顺序
    视图view没有主键,但可以添加唯一索引
    ASPxGridView KeyFieldName
    联合主键
    AspxGridView使用教程
    ASP Session 对象
  • 原文地址:https://www.cnblogs.com/xuey/p/13236767.html
Copyright © 2011-2022 走看看