享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本上都是相同的,有时就能够大幅度地减少需要实例化的类的数量。如果能把那些参数移到类实例的外面,在方法调用时将他们传递进来,就可以通过共享大幅度地减少单个实例的数目。
//所有具体享元类的超类或接口,通过这个接口,Flyweight可以接受并作用于外部状态
abstract class Flyweight {
public abstract function operation($extrinsicstate);
}
//继承Flyweight超类或实现Flyweight接口,并为内部状态增加内存空间。
class ConcreteFlyweight extends Flyweight {
public function operation($extrinsicstate) {
echo '具体Flyweight:'.$extrinsicstate.'<br/>';
}
}
//不需要共享的Flyweight子类。因为Flyweight接口共享成为可能,但它并不强制共享
class UnsharedConcreteFlyweight extends Flyweight {
public function operation($extrinsicstate) {
echo '不共享的具体Flyweight:'.$extrinsicstate.'<br/>';
}
}
//享元工厂,用来创建并管理Flyweight对象。它主要是用来确保合理地共享Flyweight,当用户请求一个FlyWeight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)
class FlyweightFactory {
private $flyweights;
function __construct(){
$this->flyweights['X'] = new ConcreteFlyweight();
$this->flyweights['Y'] = new ConcreteFlyweight();
$this->flyweights['Z'] = new ConcreteFlyweight();
}
public function getFlyweight($key) {
return $this->flyweights[$key];
}
}
//代码外部状态
$extrinsicstate = 22;
$f = new FlyweightFactory();
$fx = $f->getFlyweight('X');
$fx->operation(--$extrinsicstate);
$fx = $f->getFlyweight('Y');
$fx->operation(--$extrinsicstate);
$fx = $f->getFlyweight('Z');
$fx->operation(--$extrinsicstate);
$uf = new UnsharedConcreteFlyweight();
$uf->operation(--$extrinsicstate);
//用户
class User {
private $name;
function __construct($name) {
$this->name = $name;
}
public function __get($key) {
return isset($this->$key) ? $this->$key : null;
}
public function __set($key, $value) {
$this->$key = $value;
}
}
//网站抽象类
abstract class WebSite {
//'使用'方法需要传递‘用户’对象
public abstract function myUse(User $user);
}
//具体网站类
class ConcreteWebSite extends WebSite {
private $name = '';
function __construct($name) {
$this->name = $name;
}
//实现‘myUse’方法
public function myUse(User $user) {
echo '网站分类:'.$this->name.'用户:'.$user->name.'<br/>';
}
}
//网站工厂类
class WebSiteFactory {
private $flyweights;
//获得网站分类
public function getWebSiteCategory($key) {
if(empty($this->flyweights[$key])) {
$this->flyweights[$key] = new ConcreteWebSite($key);
}
return $this->flyweights[$key];
}
//获得网站分类总数
public function getWebSiteCount() {
return count($this->flyweights);
}
}
$f = new WebSiteFactory();
$fx = $f->getWebSiteCategory('产品展示');
$fx->myUse(new User('小菜'));
$fy = $f->getWebSiteCategory('产品展示');
$fy->myUse(new User('大鸟'));
$fz = $f->getWebSiteCategory('产品展示');
$fz->myUse(new User('娇娇'));
$fl = $f->getWebSiteCategory('博客');
$fl->myUse(new User('老顽童'));
$fm = $f->getWebSiteCategory('博客');
$fm->myUse(new User('桃谷六仙'));
$fn = $f->getWebSiteCategory('博客');
$fn->myUse(new User('南海鳄神'));
echo '得到网站分类总数为'.$f->getWebSiteCount();