学习PHP设计模式之PHP实现享元模式(Flyweight)
什么是享元模式
享元模式属于结构型模式,通过以共享的方式高效地支持大量细粒度对象的重用。在享元模式中,将对象分为两类:共享对象和非共享对象。共享对象旨在尽可能减少对象的数量,从而减少内存使用和提高性能。
为什么使用享元模式
在应用程序中,通常会创建大量的对象,这些对象可能具有相同或相似的属性,使用传统的对象创建方式,会使得内存中对象的数量不断增加,导致性能下降,甚至可能会导致程序崩溃,而采用享元模式能够有效地降低系统内存的占用率,提高程序运行效率。
实现享元模式
实现享元模式,需要重点关注如何管理和共享对象,具体如下:
-
创建享元工厂类:用于管理共享对象,通常是一个单例模式,能够在需要时创建或返回共享对象。
-
创建享元类:包括共享对象和非共享对象两部分,共享对象通常只包含属性,而非共享对象除了属性,还包括方法等。
-
创建客户端类:根据需要获取享元对象,并调用其方法。
下面是PHP代码实现。
享元类
class Flyweight {
private $sharedData;
public function __construct($sharedData) {
$this->sharedData = $sharedData;
}
public function operation($unsharedData) {
echo '共享的数据:' . $this->sharedData . ' 非共享的数据:' . $unsharedData . '<br/>';
}
}
享元工厂类
class FlyweightFactory {
private $flyweights = [];
public function getFlyweight($sharedData) {
if (!isset($this->flyweights[$sharedData])) {
$this->flyweights[$sharedData] = new Flyweight($sharedData);
}
return $this->flyweights[$sharedData];
}
}
客户端类
$factory = new FlyweightFactory();
$flyweight = $factory->getFlyweight('data1');
$flyweight->operation('data2');
$flyweight = $factory->getFlyweight('data1');
$flyweight->operation('data3');
上面的示例中,创建了享元类Flyweight,其中包含了共享属性sharedData和非共享属性unsharedData,创建了享元工厂类FlyweightFactory,用于管理共享对象。客户端通过调用getFlyweight方法获取享元对象,并调用其operation方法。
示例说明
示例1:数值转换
class Number {
private $number;
public function __construct($number) {
$this->number = $number;
}
public function toBinary() {
return decbin($this->number);
}
public function toOctal() {
return decoct($this->number);
}
public function toHex() {
return dechex($this->number);
}
}
class NumberFactory {
private $numbers = [];
public function getNumber($number) {
if (!isset($this->numbers[$number])) {
$this->numbers[$number] = new Number($number);
}
return $this->numbers[$number];
}
}
$factory = new NumberFactory();
$number1 = $factory->getNumber(10);
$number2 = $factory->getNumber(10);
$number3 = $factory->getNumber(16);
$number4 = $factory->getNumber(16);
echo $number1->toBinary() . '<br/>'; // 1010
echo $number2->toOctal() . '<br/>'; // 12
echo $number3->toHex() . '<br/>'; // a
echo $number4->toOctal() . '<br/>'; // 20
在上面的示例中,创建了Number类,其中包含了将数值转换为二进制、八进制和十六进制的方法,创建了NumberFactory工厂类,用于管理共享对象。客户端通过调用getNumber方法获取享元对象,并调用其toBinary、toOctal和toHex方法。
由于10和16被共享了,所以number1和number2是同一个对象,number3和number4是同一个对象。
示例2:文字编码
class Character {
private $char;
private $font;
public function __construct($char, $font) {
$this->char = $char;
$this->font = $font;
}
public function display() {
echo $this->char . ' (' . $this->font . ')<br/>';
}
}
class CharacterFactory {
private $characters = [];
public function getCharacter($char, $font) {
if (!isset($this->characters[$char . $font])) {
$this->characters[$char . $font] = new Character($char, $font);
}
return $this->characters[$char . $font];
}
}
$factory = new CharacterFactory();
$char1 = $factory->getCharacter('a', 'Arial');
$char2 = $factory->getCharacter('a', 'Times New Roman');
$char3 = $factory->getCharacter('b', 'Arial');
$char4 = $factory->getCharacter('a', 'Arial');
$char1->display(); // a (Arial)
$char2->display(); // a (Times New Roman)
$char3->display(); // b (Arial)
$char4->display(); // a (Arial)
在上面的示例中,创建了Character类,其中包含了字母和字体两个属性,以及用于显示字符的方法。创建了CharacterFactory工厂类,用于管理共享对象。客户端通过调用getCharacter方法获取享元对象,并调用其display方法。
由于'a'和Arial被共享了,所以char1和char4是同一个对象。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:学习php设计模式 php实现享元模式(flyweight) - Python技术站