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‘,‘测试‘);

相关推荐