深入PHP面向对象、模式与实践——生成对象(1)

来源:互联网 发布:php cookie 跨域 编辑:程序博客网 时间:2024/05/16 07:59

单例模式

  • 生成对象的问题和解决方案
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";

这里写图片描述

使用单例模式和使用全局变量都可能被误用,适度地使用单例模式可以改进系统设计。在系统中传递那些不必要的对象令人厌烦,而单例模式可以让你从中解脱。

1 0
原创粉丝点击