zhaowj00 2020-07-05
单个实例,实例就是对象。限制类只能有一个对象。
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‘,‘测试‘);
是一道经常出现在前端面试时的问题。如果只是简单的了解new关键字是实例化构造函数获取对象,是万万不能够的。更深入的层级发生了什么呢?同时面试官想从这道题里面考察什么呢?下面胡哥为各位小伙伴一一来解密。