PHP设计模式
(一)单例模式(Singleton)
● 定义
保证一个类只有一个实例,并且提供一个访问它的全局访问点。系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。
● 代码示例
1 <?php 2 3 class Singleton 4 { 5 /** 6 * @var Singleton 7 */ 8 private static $instance; 9 10 /** 11 * 不允许从外部调用以防止创建多个实例 12 * 要使用单例,必须通过 Singleton::getInstance() 方法获取实例 13 */ 14 private function __construct() 15 { 16 17 } 18 19 /** 20 * 通过懒加载获得实例(在第一次使用的时候创建) 21 */ 22 public static function getInstance() 23 { 24 if (null === static::$instance) { 25 static::$instance = new static(); 26 } 27 return static::$instance; 28 } 29 30 /** 31 * 防止实例被克隆(这会创建实例的副本) 32 */ 33 private function __clone() 34 { 35 36 } 37 38 /** 39 * 防止反序列化(这将创建它的副本) 40 */ 41 private function __wakeup() 42 { 43 44 } 45 46 }
(二)多例模式(Multiton)
● 定义
在多例模式中,多例类可以有多个实例,而且多例类必须自己创建、管理自己的实例,并向外界提供自己的实例。1. 通过实例容器保存容器。2. 利用私有构造阻止外部构造。3. 提供getInstantce()方法获取实例.
● 代码示例 两个对象通过一个类进行多次实例化
1 <?php 2 3 abstract class Multiton 4 { 5 private static $instances = array(); 6 7 public static function getInstance() 8 { 9 $key = get_called_class() . serialize(func_get_args()); 10 if (!isset(self::$instances[$key])) { 11 $rc = new ReflectionClass(get_called_class()); 12 self::$instances[$key] = $rc->newInstanceArgs(func_get_args()); 13 } 14 return self::$instances[$key]; 15 } 16 17 /** 18 * 该私有对象阻止实例被克隆 19 */ 20 private function __clone() 21 { 22 23 } 24 25 /** 26 * 该私有方法阻止实例被序列化 27 */ 28 private function __wakeup() 29 { 30 31 } 32 33 } 34 35 class Hello extends Multiton 36 { 37 public function __construct($string = 'World') 38 { 39 echo "Hello $string\n"; 40 } 41 } 42 43 class GoodBye extends Multiton 44 { 45 public function __construct($string = 'my', $string2 = 'darling') 46 { 47 echo "Goodbye $string $string2\n"; 48 } 49 } 50 $a = Hello::getInstance('World'); 51 $b = Hello::getInstance('bob'); 52 // $a !== $b 53 54 $c = Hello::getInstance('World'); 55 // $a === $c 56 57 $d = GoodBye::getInstance(); 58 $e = GoodBye::getInstance(); 59 // $d === $e 60 61 $f = GoodBye::getInstance('your'); 62 // $d !== $f
(三)工厂方法模式(Factory Method)
● 定义
将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类
● 代码示例 :小成有一间塑料加工厂(仅生产 A 类产品);随着客户需求的变化,客户需要生产 B 类产品。改变原有塑料加工厂的配置和变化非常困难,假设下一次客户需要再发生变化,再次改变将增大非常大的成本;小成决定置办塑料分厂 B 来生产 B 类产品。
<?php abstract class Product { public abstract function Show(); } //具体产品A类 class ProductA extends Product { public function Show() { echo "生产出了产品A"; } } //具体产品B类 class ProductB extends Product { public function Show() { echo "生产出了产品B"; } } abstract class Factory { public abstract function Manufacture(); } //工厂A类 - 生产A类产品 class FactoryA extends Factory { public function Manufacture() { return new ProductA(); } } //工厂B类 - 生产B类产品 class FactoryB extends Factory { public function Manufacture() { return new ProductB(); } } $a = new FactoryA(); $a->Manufacture()->show();//生产出了产品A echo "<br/>"; $b = new FactoryB(); $b->Manufacture()->show();//生产出了产品B