爲了節約內存的使用,享元模式會盡可能使相似的對象共享內存。在大量相似對象被使用的狀況中這是十分必要的。經常使用作法是在外部數據結構中保存相似對象的狀態,並在須要時將他們傳遞給享元對象。php
<?php namespace DesignPatterns\Structural\Flyweight; /** * 建立享元接口 FlyweightInterface 。 */ interface FlyweightInterface { /** * 建立傳遞函數。 * 返回字符串格式數據。 */ public function render(string $extrinsicState): string; }
<?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); } }
<?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); } }
<?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 成長指南+行業問題解決總綱(持續更新)sql
面試10家公司,收穫9個offer,2020年PHP 面試問題shell
★若是喜歡個人文章,想與更多資深開發者一塊兒交流學習的話,獲取更多大廠面試相關技術諮詢和指導,歡迎加入咱們的羣啊,暗號:phpzh(君羊號碼856460874)。設計模式
內容不錯的話但願你們支持鼓勵下點個贊/喜歡,歡迎一塊兒來交流;另外若是有什麼問題 建議 想看的內容能夠在評論提出服務器