小孩画画的时,会使用许多不同颜色的彩色笔,比如使用绿色笔画画这个,然后用红色画画那个,再用蓝色画画蓝天等。这些彩色笔,可以持续使用,也可以交替来回使用。这些不同颜色画笔都是独立个体,不和其他画笔有必要的联系,也就是说,没有规定使用绿色之后才能使用蓝色,或者使用蓝色之后不能红色之类的规定。
在面向对象中,类似画笔这样,可以来回交替使用,且都为独立个体(没有上下文关系),为了避免对象的重复创建,节省内存空间。可以使用享元模式实现
不使用享元模式的代码:
class RedColor{
public function color(){
echo "drawRed";
}
}
class GreenColor{
public function color(){
echo "drawGreen";
}
}
class BlueColor{
public function color(){
echo "drawBlue";
}
}
class Picture{ //不复用,每次都必须实例化对象
public function draw($color){
$colorObj = null;
switch ($color) {
case 'red':
$colorObj = new RedColor();
break;
case 'green':
$colorObj = new GreenColor();
break;
case 'blue':
$colorObj = new BlueColor();
default:
break;
}
if($colorObj)
$colorObj->color();
else
echo "nothing";
}
}
$picture = new Picture();
$picture->draw('red');
$picture->draw('green');
$picture->draw('red');
$picture->draw('blue');
$picture->draw('red');
上述代码中,要重复创建画笔对象
享元模式代码:
class FlyWeightPicture{ //复用
private $colorObjs = [];
public function draw($color){
$colorObj = $this->existColorObj($color);
$colorObj->color();
}
private function existColorObj($color){
if(isset($this->colorObjs[$color])){
return $this->colorObjs[$color];
}
$colorObj = null;
switch ($color) {
case 'red':
$colorObj = new RedColor();
break;
case 'green':
$colorObj = new GreenColor();
break;
case 'blue':
$colorObj = new BlueColor();
default:
break;
}
$this->colorObjs[$color] = $colorObj;
return $colorObj;
}
}
echo "<br>-------------------<br>";
$picture = new FlyWeightPicture();
$picture->draw('red');
$picture->draw('green');
$picture->draw('red');
$picture->draw('blue');
$picture->draw('red');
上述代码减少对象的创建,节省了 内存空间
总结
享元模式:复用对象,而不创建对象。而这个对象应该没有上下文关系
优点:
1.减少运行时对象实例个数,节省内存
2.将许多“虚拟”对象的状态集中管理
缺点:一旦你实现了它,那么单个的逻辑实例将无法拥有独立而不同的行为
设计模式,享元模式 Flyweigth