深入PHP面向对象、模式与实践——生成对象(1)
2017-04-01 14:51
721 查看
单例模式
生成对象的问题和解决方案abstract class Employee { protected $name; public function __construct($name) { $this->name = $name; } abstract function fire(); } class Minion extends Employee { function fire() { print "{$this->name}:I'll clear my desk\n"; } } class NastyBoss { private $employees = array(); function addEmployee($employeeName) { $this->employees[] = new Minion($employeeName); } function projectFail() { if (count($this->employees) > 0) { $emp = array_pop($this->employees); $emp->fire(); } } } $boss = new NastyBoss(); $boss->addEmployee("harry"); $boss->addEmployee("bob"); $boss->addEmployee("mary"); $boss->projectFail();
由于在NastyBoss类中直接实例化Minion对象,代码的灵活性受到限制。如果NastyBoss对象可以使用Employee类的任何实例,那么代码在运行时就能应对更多特殊的Employee。如下类图:
如果NastyBoss类不实例化Minion对象,那么Minion对象从何而来?在方法声明中限制参数类型来巧妙避开这个问题,然后除了在测试时实例化对象,在其他时候尽量避免提及。
如果是这里存在一个原则的话,那便是“把对象实例化的工作委托出来”。我们可以委托一个独立的类或方法来生成Employee对象。
abstract class Employee { protected $name; private static $types = array("minion", 'clueup', 'wellconnected'); static function recruit($name) { $num = rand(1, count(self::$types)) - 1; $class = self::$types[$num]; return new $class($name); } public function __construct($name) { $this->name = $name; } abstract function fire(); } class wellConnected extends Employee { function fire() { print "{$this->name}: i'll call my dad\n"; } } $boss = new NastyBoss(); $boss->addEmployee(Employee::recruit("harry")); $boss->addEmployee(Employee::recruit("bob")); $boss->addEmployee(Employee::recruit("mary"));
单例模式
经过良好设计的系统一般通过方法调用来传递对象实例。每个类都会与背景环境保持独立,并通过清晰的通信方式来与系统中其他部分进行协作。有时你需要使用一些作为对象间沟通渠道的类,此时就不得不引入依赖关系。
下面创建一个无法从自身外部来创建实例的类:
class Preferences { private $props = array(); private static $instance; private function __construct() { } public static function getInstance() { if (empty(self::$instance)) { self::$instance = new Preferences(); } return self::$instance; } public function setProperty($key, $val) { $this->props[$key] = $val; } public function getProperty($key) { return $this->props[$key]; } } $pref = Preferences::getInstance(); $pref->setProperty("name", "matt"); unset($pref); $pref2 = Preferences::getInstance(); print $pref2->getProperty("name") . "\n";
使用单例模式和使用全局变量都可能被误用,适度地使用单例模式可以改进系统设计。在系统中传递那些不必要的对象令人厌烦,而单例模式可以让你从中解脱。
相关文章推荐
- 深入PHP面向对象、模式与实践——生成对象(2)
- 深入PHP面向对象、模式与实践——生成对象(3)
- 深入PHP面向对象、模式与实践——组合模式
- 深入php面向对象、模式与实践
- 深入PHP面向对象、模式与实践——让面向对象编程更加灵活的模式(3)
- 深入PHP面向对象、模式与实践——高级特性(4)
- 深入PHP面向对象、模式与实践——执行及描述任务(4)
- 深入PHP面向对象、模式与实践——执行及描述任务(5)
- 深入PHP面向对象、模式与实践---PHP和对象
- 深入PHP面向对象、模式与实践——模式原则(1)
- 深入PHP面向对象、模式与实践
- 深入PHP面向对象、模式与实践——对象与设计
- 深入php面向对象、模式与实践
- 深入PHP面向对象、模式与实践——执行及描述任务(1)
- 深入PHP面向对象、模式与实践——高级特性(6)
- 深入PHP面向对象、模式与实践——对象工具(2)
- 深入PHP面向对象、模式与实践——对象
- 深入PHP面向对象、模式与实践——企业模式(3)
- 深入PHP面向对象、模式与实践——高级特性(3)
- 深入PHP面向对象、模式与实践——高级特性(1)