PHP设计模式-享元模式

        从字面意义上看来,享元就是共享一些元素。它解决的是一个轻量级的创建或拷贝。什么意思呢?

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

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.享元模式的目的在于,通过共享一些对象的公共数据,减少创建和复制所带来的性能消耗。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值