单例模式
<?php //单例模式 class Student{ private static $instance = null; //构造器私有化:禁止从类外部实例化 private function __construct(){} //克隆方法私有化:禁止从外部克隆对象 private function __clone(){} //保存用户的姓名信息 private $name = ''; public static function getInstance() { //检测当前类属性$instance是否已经保存了当前类的实例 if (self::$instance == null) { //如果没有,则创建当前类的实例 self::$instance = new self(); } //如果已经有了当前类实例,就直接返回,不要重复创建类实例 return self::$instance; } //设置学生姓名 public function set($name) { $this->name = $name; } //读取学生姓名 public function get() { return $this->name; } } //实例化Student类 $student = Student::getInstance(); $student->set('爱丽丝'); echo $student->get();
运行实例 »
点击 "运行实例" 按钮查看在线实例
工厂模式
<?php //工厂模式实例 //声明形状类 class Shape { //声明静态方法create,根据容器形状不同,创建不同图形类的实例 public static function create($type,array $size=[]) { //检测形状? switch ($type) { //长方形 case 'rectangle': return new Rectangle($size[0],$size[1]); break; //三角形 case 'triangle': return new Triangle($size[0],$size[1]); break; } } } //声明长方形类 class Rectangle { private $width; //宽度 private $height; //高级 public function __construct($witch,$height) { $this->width = $witch; $this->height = $height; } //计算长方形面积: 宽 * 高 public function area() { return $this->width * $this->height; } } //声明三角形类 class Triangle { private $bottom; //底边 private $height; //边长 public function __construct($bottom,$height) { $this->bottom = $bottom; $this->height = $height; } //计算三角形面积: (底 * 高) / 2 public function area() { return ($this->bottom * $this->height)/2; } } //使用静态方法来实例化形状类,而不是用传统的new 关键字 //并根据形状类型参数的不同,来实例化不同的类,生成不同的对象 $rectangle = Shape::create('rectangle',[20,5]); echo '长方形的面积是'.$rectangle->area(); echo '<hr>'; $triangle = Shape::create('triangle',[9,3]); echo '三角形的面积是'.$triangle->area();
运行实例 »
点击 "运行实例" 按钮查看在线实例
注册树模式
<?php //先声明三个类,一会丢进对象树上中 class Demo1 {} class Demo2 {} class Demo3 {} //声明对象注册树类 class Register { //静态属性中保存着所有已经挂载到树上的对象 public static $objs = []; //将对象挂载到树上 public static function set($index,$obj) { self::$objs[$index] = $obj; } //取出对象使用 public static function get($index) { return self::$objs[$index]; } //已经无效的对象,及时销毁,节省资源 public static function del($index) { unset(self::$objs[$index]); } } //先将三个类实例化后挂载到对象树上 Register::set('demo1',new Demo1); Register::set('demo2',new Demo2); Register::set('demo3',new Demo3); //检测是否上树? var_dump(Register::$objs); echo '<hr>'; echo '<pre>'.print_r(Register::$objs,true).'</pre>'; echo '<hr>'; //用注册类的get方法查看 var_dump(Register::get('demo2')); //删除对象池中的某个实例对象 Register::del('demo2'); //再次查看demo2对象,已经不能被查看了,因为被销毁了 var_dump(Register::get('demo2'));
运行实例 »
点击 "运行实例" 按钮查看在线实例
总结:
1.单例模式
单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
优点:
一、实例控制
单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。
二、灵活性
因为类控制了实例化过程,所以类可以灵活更改实例化过程。
2.工厂模式
工厂模式就是专门负责将大量有共同接口(或者共同抽象父类)的类实例化,而且不必事先知道每次是要实例化哪一个类的模式。它定义一个用于创建对象的接口,由子类决定实例化哪一个类。
优点:
工厂类是整个模式的关键.包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象.通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的.明确了各自的职责和权利,有利于整个软件体系结构的优化。
缺点
由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。
当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利;
这些缺点在工厂方法模式中得到了一定的克服。
使用场景:
工厂类负责创建的对象比较少;
客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。
注册册树模式
也叫作注册模式或者注册器模式,它的定位可能和“简单工厂”差不多,都是一种简化的,实用的技巧,但都不算在真正的的23种设计模式之中。假如要更形象的理解注册树模式的话,就可以把它看成一颗长满水果的树,如果你向这棵注册树上添加一个对象,那么这个树上就会长出一个水果。这个水果在你想要它的时候随时可以拿到它,在你以后都不会碰它的时候可以除去它。【$objects=数 、 set()=长水果 、 get()=拿到水果 、 _unset()=去除水果】
注册树模式的难易程度应该是和单例模式相差不多,至于注册树模式的好处和作用,有好人都说过了这里引用一下别人的话。
引用:
首先,单例模式创建唯一对象的过程本身还有一种判断,即判断对象是否存在。存在则返回对象,不存在则创建对象并返回。 每次创建实例对象都要存在这么一层判断。 工厂模式更多考虑的是扩展维护的问题。 总的来说,单例模式和工厂模式可以产生更加合理的对象。怎么方便调用这些对象呢?而且在项目内如此建立的对象好像散兵游勇一样,不便统筹管理安排啊。因而,注册树模式应运而生。不管你是通过单例模式还是工厂模式还是二者结合生成的对象,都统统给我“插到”注册树上。我用某个对象的时候,直接从注册树上取一下就好。这和我们使用全局变量一样的方便实用。