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‘,‘测试‘); 相关推荐
  heyboz    2020-10-21  
   lukezhong    2020-10-14  
   tangxiong0    2020-09-03  
   寻常白昼    2020-06-14  
   luvhl    2020-06-08  
   oXiaoChong    2020-06-03  
   chenlxhf    2020-05-06  
 是一道经常出现在前端面试时的问题。如果只是简单的了解new关键字是实例化构造函数获取对象,是万万不能够的。更深入的层级发生了什么呢?同时面试官想从这道题里面考察什么呢?下面胡哥为各位小伙伴一一来解密。
  haohong    2020-04-08  
   JF0    2020-03-20  
   fanhuasijin    2020-03-01  
   横云断岭    2020-02-20  
   zhouyuqi    2020-01-20  
   kong000dao0    2020-01-11  
   年轻就要对味    2014-07-11  
   发条戏子    2019-12-27  
   王志龙    2019-12-26  
   duanlove技术路途    2019-12-20