写点什么

结构型设计模式 - 享元 (缓存)Flyweight

作者:菜皮日记
  • 2023-09-08
    北京
  • 本文字数:1981 字

    阅读完需:约 6 分钟

简介

享元模式更常见的叫法是缓存或 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_pinkMercedes Benz_C300_blackMercedes Benz_C500_redBMW_M5_redBMW_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_pinkMercedes Benz_C300_blackMercedes Benz_C500_redBMW_M5_redBMW_X6_whiteBMW_X1_red
复制代码


用户头像

菜皮日记

关注

全干程序员 2018-08-08 加入

还未添加个人简介

评论

发布
暂无评论
结构型设计模式-享元(缓存)Flyweight_设计模式_菜皮日记_InfoQ写作社区