本文同步更新於blog
情境:这是公司生产的文字积木
<?php
namespace App\Flyweight\Blocks;
class ConcreteBlock
{
/**
* @var string
*/
protected $shape;
/**
* @var string
*/
public $word;
/**
* @param string $shape
* @param string $word
*/
public function __construct(string $shape, string $word)
{
$this->shape = $shape;
$this->word = $word;
}
/**
* @return string
*/
public function getShape(): string
{
return $this->shape;
}
/**
* @return string
*/
public function getWord(): string
{
return $this->word;
}
}
namespace App\Flyweight\Blocks;
<?php
namespace App\Flyweight\Blocks;
use App\Flyweight\Blocks\ConcreteBlock;
class Program
{
/**
* @return array
*/
public function getBlocks(): array
{
$firstBlock = new ConcreteBlock('star', 'B');
$secondBlock = new ConcreteBlock('square', 'E');
$thirdBlock = new ConcreteBlock('square', 'A');
$fourthBlock = new ConcreteBlock('square', 'R');
return [$firstBlock, $secondBlock, $thirdBlock, $fourthBlock];
}
}
随着积木越卖越好,我们会创建出许多Block,
它们要显示的文字各不相同,但形状大概就那几种。
我们决定改变积木的实作,不纪录显示文字於积木的状态中。
抽离出共用的形状部分,来节省记忆体的消耗。
<?php
namespace App\Flyweight\Blocks\Contracts;
interface Block
{
public function getShape();
public function display(string $word): string;
}
之後我们要显示文字时,会使用display()方法。
<?php
namespace App\Flyweight\Blocks;
use App\Flyweight\Blocks\Contracts\Block;
class ConcreteBlock implements Block
{
/**
* @var string
*/
protected $shape;
/**
* @param string $shape
*/
public function __construct(string $shape)
{
$this->shape = $shape;
}
/**
* @return string
*/
public function getShape(): string
{
return $this->shape;
}
/**
* @param string $word
* @return string
*/
public function display(string $word): string
{
return $word;
}
}
<?php
namespace App\Flyweight\Blocks;
use App\Flyweight\Blocks\ConcreteBlock;
use App\Flyweight\Blocks\Contracts\Block;
class BlockFactory
{
/**
* @var Block[]
*/
protected $blocks;
/**
* @param string $shape
* @return ConcreteBlock
*/
public function getBlock(string $shape): Block
{
if (!isset($this->blocks[$shape])) {
$this->blocks[$shape] = new ConcreteBlock($shape);
}
return $this->blocks[$shape];
}
}
<?php
namespace App\Flyweight\Blocks;
use App\Flyweight\Blocks\Block;
class Program
{
/**
* @return array
*/
public function getBlocks(): array
{
$blockFactory = new BlockFactory();
$firstBlock = $blockFactory->getBlock('star');
// $firstBlock->display('B');
$secondBlock = $blockFactory->getBlock('square');
// $secondBlock->display('E');
$thirdBlock = $blockFactory->getBlock('square');
// $thirdBlock->display('A');
$fourthBlock = $blockFactory->getBlock('square');
// $fourthBlock->display('R');
return [$firstBlock, $secondBlock, $thirdBlock, $fourthBlock];
}
}
当客户端要显示文字时,再呼叫display()方法。
[单一职责原则]
我们将管理内部状态与管理外部状态,视为两种不同的职责。
透过区分两者,我们便可以用 简单工厂模式 搭配 单例模式,
切出细粒度的物件,来共用相同的程序码。
其蝇量类别只纪录内部状态且创建後便不会改变。
[开放封闭原则]
透过工厂,我们可以修改积木本身的实作(例如换厂牌),而不影响客户端。
当客户端修改外部状态时,也不影响原本纯内部状态的积木。
[里氏替换原则]
工厂依赖於抽象的积木介面。
实体积木实作了抽象的积木介面。
最後附上类别图:
(注:若不熟悉 UML 类别图,可参考UML类别图说明。)
ʕ •ᴥ•ʔ:原来共享经济是用了蝇量模式的概念啊。
<<: 虚拟主机是什麽又该如何选择?2020 最新台湾虚拟主机推荐比较
前言 我们现在有了 Nuxt.js 建立的环境、有了 Vuex 来做资料的处理,现在就差资料要从哪里...
当一个模型的训练资料和测试资料,彼此之间的资料分布有不匹配(mismatch)时,模 型的性能会出现...
开始上班後,从来没放过这麽长的假,而且还没出门旅行。给自己的每天的例行功课就是看书跟写日记,昨天把...
战略资讯系统 中台架构其实是一种整体资讯架构订定的思维,其目的是为了迎接企业不断创新的挑战,在『变是...
Lazy loading 是广为人知的网页优化技巧,尤其应用在图片上时能够大幅减少效能和流量的浪费,...