PHP設計模式之享元模式(Flyweight)程式碼例項大全(18)
阿新 • • 發佈:2020-09-16
目的
為了節約記憶體的使用,享元模式會盡量使類似的物件共享記憶體。在大量類似物件被使用的情況中這是十分必要的。常用做法是在外部資料結構中儲存類似物件的狀態,並在需要時將他們傳遞給享元物件。
UML 圖
程式碼
- FlyweightInterface.php
<?php
namespace DesignPatterns\Structural\Flyweight;
/**
* 建立享元介面 FlyweightInterface 。
*/
interface FlyweightInterface
{
/**
* 建立傳遞函式。
* 返回字串格式資料。
*/
public function render(string $extrinsicState): string;
}
- CharacterFlyweight.php
<?php namespace DesignPatterns\Structural\Flyweight; /** * 假如可以的話,實現享元介面並增加記憶體儲存內部狀態。 * 具體的享元例項被工廠類的方法共享。 */ class CharacterFlyweight implements FlyweightInterface { /** * 任何具體的享元物件儲存的狀態必須獨立於其執行環境。 * 享元物件呈現的特點,往往就是對應的編碼的特點。 * * @var string */ private $name; /** * 輸入一個字串物件 $name。 */ public function __construct(string $name) { $this->name = $name; } /** * 實現 FlyweightInterface 中的傳遞方法 render() 。 */ public function render(string $font): string { // 享元物件需要客戶端提供環境依賴資訊來自我定製。 // 外在狀態經常包含享元物件呈現的特點,例如字元。 return sprintf('Character %s with font %s', $this->name, $font); } }
- FlyweightFactory.php
<?php namespace DesignPatterns\Structural\Flyweight; /** * 工廠類會管理分享享元類,客戶端不應該直接將他們例項化。 * 但可以讓工廠類負責返回現有的物件或建立新的物件。 */ class FlyweightFactory implements \Countable { /** * @var CharacterFlyweight[] * 定義享元特徵陣列。 * 用於儲存不同的享元特徵。 */ private $pool = []; /** * 輸入字串格式資料 $name。 * 返回 CharacterFlyweight 物件。 */ public function get(string $name): CharacterFlyweight { if (!isset($this->pool[$name])) { $this->pool[$name] = new CharacterFlyweight($name); } return $this->pool[$name]; } /** * 返回享元特徵個數。 */ public function count(): int { return count($this->pool); } }
測試
- Tests/FlyweightTest.php
<?php
namespace DesignPatterns\Structural\Flyweight\Tests;
use DesignPatterns\Structural\Flyweight\FlyweightFactory;
use PHPUnit\Framework\TestCase;
/**
* 建立自動化測試單元 FlyweightTest 。
*/
class FlyweightTest extends TestCase
{
private $characters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
private $fonts = ['Arial', 'Times New Roman', 'Verdana', 'Helvetica'];
public function testFlyweight()
{
$factory = new FlyweightFactory();
foreach ($this->characters as $char) {
foreach ($this->fonts as $font) {
$flyweight = $factory->get($char);
$rendered = $flyweight->render($font);
$this->assertEquals(sprintf('Character %s with font %s', $char, $font), $rendered);
}
}
// 享元模式會保證例項被分享。
// 相比擁有成百上千的私有物件,
// 必須要有一個例項代表所有被重複使用來顯示不同單詞的字元。
$this->assertCount(count($this->characters), $factory);
}
}
PHP 網際網路架構師 50K 成長指南+行業問題解決總綱(持續更新)
面試10家公司,收穫9個offer,2020年PHP 面試問題
★如果喜歡我的文章,想與更多資深開發者一起交流學習的話,獲取更多大廠面試相關技術諮詢和指導,歡迎加入我們的群啊,暗號:phpzh(君羊號碼856460874)。
內容不錯的話希望大家支援鼓勵下點個贊/喜歡,歡迎一起來交流;另外如果有什麼問題 建議 想看的內容可以在評論提出