PHP设计模式-享元模式

来源:互联网 发布:阿里云域名控制面板 编辑:程序博客网 时间:2024/05/18 12:41
        从字面意义上看来,享元就是共享一些元素。它解决的是一个轻量级的创建或拷贝。什么意思呢?

        例如:我有一个用企业用户管理的功能模块,用户有名字,和公司的一些基本信息, 公司的信息是需要根据用户的名字到数据库中查询的。

class CompanyInfo{//公司名称protected $_name;//公司地址protected $_addr;//初始化public function __construct($userName){$result = $this->getInfoByUserName($userName);$this->_name = $result['name'];$this->_addr = $result['addr'];}//根据用户名到数据库中查询公司信息public function getInfoByUserName($userName){//返回查询结果,代码略}}class User{protected $_name;protected $_companyInfo;//用户初始化public function __construct($name){$this->_name = $name;$this->_companyInfo = new CompanyInfo($this->_name);}}//创建用户$andrew = new User('andrew');$delia  = new User('delia');
        这样没什么问题,假设如果我们知道,andrew和delia都是同一个公司的人。那么他们的信息应该是一样的,就没必要重复从数据库中读取信息了。但名字可能不一样。那我们就把andrew对象复制一下,然后把名字改了不就行了嘛。嗯,很简单。那user对象就缺少一个设置名字的方法。
class User{protected $_name;protected $_companyInfo;//用户初始化public function __construct($name){$this->_name = $name;$this->_companyInfo = new CompanyInfo($this->_name);}//设置名字public function setName($name){$this->_name = $name;}}$andrew = new User('andrew');$delia  = clone $andrew;$delia->setName('delia');
        好了,这样,一个享元模式就完成了。什么?这么简单。对的,就是这么简单。在php中当复制一个对象时,它的companyInfo对象会复制一个引用。这样你就不用再从数据库中读取信息。直接两个人共享这一个信息就可以了。同时我们修改一下公司的信息,两个人都会发现改变。好,那我们试一下:

class CompanyInfo{    //公司名称    protected $_name;    //公司地址    protected $_addr;    //初始化    public function __construct($userName)    {        $result = $this->getInfoByUserName($userName);        $this->_name = $result['name'];        $this->_addr = $result['addr'];    }    //根据用户名到数据库中查询公司信息,在这里我们假设了一个值    public function getInfoByUserName($userName)    {        return array(            'name' => 'qihoo',            'addr' => 'beijing',        );    }    //设置公司名    public function setName($name)    {        $this->_name = $name;    }}class User{    protected $_name;    protected $_companyInfo;    //用户初始化    public function __construct($name)    {        $this->_name = $name;        $this->_companyInfo = new CompanyInfo($this->_name);    }    //设置名字    public function setName($name)    {        $this->_name = $name;    }    //获取公司信息    public function getCompanyInfo()    {        return $this->_companyInfo;    }}$andrew = new User('andrew');$delia = clone $andrew;$delia->setName('delia');$andrew->getCompanyInfo()->setName('cc');var_dump($andrew);var_dump($delia);
        输出结果如下:
object(User)#1 (2) {  ["_name:protected"]=>  string(6) "andrew"  ["_companyInfo:protected"]=>  object(CompanyInfo)#2 (2) {    ["_name:protected"]=>    string(2) "cc"    ["_addr:protected"]=>    string(7) "beijing"  }}object(User)#3 (2) {  ["_name:protected"]=>  string(5) "delia"  ["_companyInfo:protected"]=>  object(CompanyInfo)#2 (2) {    ["_name:protected"]=>    string(2) "cc"    ["_addr:protected"]=>    string(7) "beijing"  }}
        我们可以看到,andrew的名字发生改变后不会对delia这个用户的名字产生影响,但是,andrew的companyInfo发生改变后,两个都发生了改变。也就是说,andrew和delia共享了companyInfo.享元模式的目的在于,通过共享一些对象的公共数据,减少创建和复制所带来的性能消耗。