简介
享元模式更常见的叫法是缓存或 cache,一个对象只创立一次,之后始终复用这一对象。
跟单例不同在于,单例是全局只有惟一一个对象,所有人一起用同一个对象,且该对象是提前预设好的,不能定制。
而享元则能够依据参数不同创立出不同的实例,不过实例一旦创立就只保留一份,之后再次创立雷同参数的实例则返回该对象,供所有援用的中央应用,援用方之间共享同一份享元实例的数据。
过程有点像定制化的单例模式。
角色
-
Flyweight 享元类
定制化的业务实体,依据不同须要可能定制不同的享元类,但一旦创立出一个享元类,当前都复用这一个类
-
FlyweightFactory 享元工厂类
用来创立和缓存享元实体的中央
类图
代码
class Flyweight
{
private $sharedState;
public function __construct($sharedState)
{$this->sharedState = $sharedState;}
public function operation($uniqueState): void
{$s = json_encode($this->sharedState);
$u = json_encode($uniqueState);
echo "Flyweight: Displaying shared ($s) and unique ($u) state.\n";
}
}
class FlyweightFactory
{private $flyweights = [];
public function __construct(array $initialFlyweights)
{foreach ($initialFlyweights as $state) {$this->flyweights[$this->getKey($state)] = new Flyweight($state);
}
}
private function getKey(array $state): string
{ksort($state);
return implode("_", $state);
}
public function getFlyweight(array $sharedState): Flyweight
{$key = $this->getKey($sharedState);
if (!isset($this->flyweights[$key])) {
echo "FlyweightFactory: Can't find a flyweight, creating new one.\n";
$this->flyweights[$key] = new Flyweight($sharedState);
} else {echo "FlyweightFactory: Reusing existing flyweight.\n";}
return $this->flyweights[$key];
}
public function listFlyweights(): void
{$count = count($this->flyweights);
echo "\nFlyweightFactory: I have $count flyweights:\n";
foreach ($this->flyweights as $key => $flyweight) {echo $key . "\n";}
}
}
$factory = new FlyweightFactory([["Chevrolet", "Camaro2018", "pink"],
["Mercedes Benz", "C300", "black"],
["Mercedes Benz", "C500", "red"],
["BMW", "M5", "red"],
["BMW", "X6", "white"],
]);
$factory->listFlyweights();
function addCarToPoliceDatabase(
FlyweightFactory $ff, $plates, $owner,
$brand, $model, $color
) {
echo "\nClient: Adding a car to database.\n";
$flyweight = $ff->getFlyweight([$brand, $model, $color]);
$flyweight->operation([$plates, $owner]);
}
addCarToPoliceDatabase($factory,
"CL234IR",
"James Doe",
"BMW",
"M5",
"red"
);
addCarToPoliceDatabase($factory,
"CL234IR",
"James Doe",
"BMW",
"X1",
"red"
);
$factory->listFlyweights();
output:
FlyweightFactory: I have 5 flyweights:
Chevrolet_Camaro2018_pink
Mercedes Benz_C300_black
Mercedes Benz_C500_red
BMW_M5_red
BMW_X6_white
Client: Adding a car to database.
FlyweightFactory: Reusing existing flyweight.
Flyweight: Displaying shared (["BMW","M5","red"]) and unique (["CL234IR","James Doe"]) state.
Client: Adding a car to database.
FlyweightFactory: Can't find a flyweight, creating new one.
Flyweight: Displaying shared (["BMW","X1","red"]) and unique (["CL234IR","James Doe"]) state.
FlyweightFactory: I have 6 flyweights:
Chevrolet_Camaro2018_pink
Mercedes Benz_C300_black
Mercedes Benz_C500_red
BMW_M5_red
BMW_X6_white
BMW_X1_red
本文由 mdnice 多平台公布