享元模式英文称为“Flyweight Pattern”,我非常感谢将Flyweight Pattern翻译成享元模式的那位强人,因为这个词将这个模式使用的方式明白得表示了出来;如果翻译成为羽量级模式或者蝇量级模式等等,虽然可以含蓄的表现出使用此模式达到的目的,但是还是没有抓住此模式的关键。
享元模式的定义为:采用一个共享来避免大量拥有相同内容对象的开销。这种开销中最常见、直观的就是内存的损耗。享元模式以共享的方式高效的支持大量的细粒度对象。
在名字和定义中都体现出了共享这一个核心概念,那么怎么来实现共享呢?要知道每个事物都是不同的,但是又有一定的共性,如果只有完全相同的事物才能共享,那么享元模式可以说就是不可行的;因此我们应该尽量将事物的共性共享,而又保留它的个性。为了做到这点,享元模式中区分了内蕴状态和外蕴状态。内蕴状态就是共性,外蕴状态就是个性了。
注:共享的对象必须是不可变的,不然一变则全变(如果有这种需求除外)。
内蕴状态存储在享元内部,不会随环境的改变而有所不同,是可以共享的;外蕴状态是不可以共享的,它随环境的改变而改变的,因此外蕴状态是由客户端来保持(因为环境的变化是由客户端引起的)。在每个具体的环境下,客户端将外蕴状态传递给享元,从而创建不同的对象出来。
先看看下面程序,大概了解下享元模式。
复制代码 代码如下:
/**
* 享元模式
*
* 运用享元技术有效的支持大量细粒度的对象
*/
class CD
{
private $_title = null;
private $_artist = null;
public function setTitle($title)
{
$this->_title = $title;
}
public function getTitle()
{
return $this->_title;
}
public function setArtist($artist)
{
$this->_artist = $artist;
}
public function getArtist($artist)
{
return $this->_artist;
}
}
class Artist
{
private $_name;
public function __construct($name)
{
echo "construct ".$name."
";
$this->_name = $name;
}
public function getName()
{
return $this->_name;
}
}
class ArtistFactory
{
private $_artists = array();
public function getArtist($name)
{
if(isset($this->_artists[$name]))
{
return $this->_artists[$name];
} else {
$objArtist = new Artist($name);
$this->_artists[$name] = $objArtist;
return $objArtist;
}
}
}
$objArtistFactory = new ArtistFactory();
$objCD1 = new CD();
$objCD1->setTitle("title1");
$objCD1->setArtist($objArtistFactory->getArtist('artist1'));
$objCD2 = new CD();
$objCD2->setTitle("title2");
$objCD2->setArtist($objArtistFactory->getArtist('artist2'));
$objCD3 = new CD();
$objCD3->setTitle("title3");
$objCD3->setArtist($objArtistFactory->getArtist('artist1'));
享元模式的精要有三点:
面向对象虽然很好地解决了抽象性的问题,但是对于一个实际运行的软件系统,我们还需要考虑面向对象的代价问题,享元模式解决的就是面向对象的代价问题。享元模式采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。
플라이웨이트 모드는 일반적인 프로젝트 개발에서는 일반적으로 사용되지 않지만, 시스템 성능 문제를 해결하기 위해 기본 시스템 개발에 자주 사용됩니다. Java 및 .Net의 문자열 유형은 플라이웨이트 패턴을 사용합니다. 문자열 개체 s1이 Java 또는 .NET에서 생성된 경우 다음에 동일한 문자열 s2가 생성되면 시스템은 s2의 참조를 s1이 참조하는 특정 개체로 가리키게 되며, 이는 메모리에서 동일한 문자열 공유를 달성합니다. . s1="abc" 작업이 실행될 때마다 새로운 문자열 개체가 생성되면 메모리 오버헤드가 매우 커집니다.
위에서 내용의 측면을 포함하여 PHP 디자인 패턴 FlyWeight 플라이웨이트 패턴을 소개했습니다. PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.