您的位置:首页 > 编程语言 > PHP开发

深入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