php设计模式 FlyWeight (享元模式)_PHP教程
享元模式英文称为“Flyweight Pattern”,我非常感谢将Flyweight Pattern翻译成享元模式的那位强人,因为这个词将这个模式使用的方式明白得表示了出来;如果翻译成为羽量级模式或者蝇量级模式等等,虽然可以含蓄的表现出使用此模式达到的目的,但是还是没有抓住此模式的关键。
享元模式的定义为:采用一个共享来避免大量拥有相同内容对象的开销。这种开销中最常见、直观的就是内存的损耗。享元模式以共享的方式高效的支持大量的细粒度对象。
在名字和定义中都体现出了共享这一个核心概念,那么怎么来实现共享呢?要知道每个事物都是不同的,但是又有一定的共性,如果只有完全相同的事物才能共享,那么享元模式可以说就是不可行的;因此我们应该尽量将事物的共性共享,而又保留它的个性。为了做到这点,享元模式中区分了内蕴状态和外蕴状态。内蕴状态就是共性,外蕴状态就是个性了。
注:共享的对象必须是不可变的,不然一变则全变(如果有这种需求除外)。
内蕴状态存储在享元内部,不会随环境的改变而有所不同,是可以共享的;外蕴状态是不可以共享的,它随环境的改变而改变的,因此外蕴状态是由客户端来保持(因为环境的变化是由客户端引起的)。在每个具体的环境下,客户端将外蕴状态传递给享元,从而创建不同的对象出来。
先看看下面程序,大概了解下享元模式。
/**
* 享元模式
*
* 运用享元技术有效的支持大量细粒度的对象
*/
class CD
{
private $_title = null;
private $_artist = null;
public function setTitle($title)
{
$this->_title = $title;
}
public function getTitle()
{
return $this->_title;
}
public function setArtist($artist)
{
$this->_artist = $artist;
}
public function getArtist($artist)
{
return $this->_artist;
}
}
class Artist
{
private $_name;
public function __construct($name)
{
echo "construct ".$name."
";
$this->_name = $name;
}
public function getName()
{
return $this->_name;
}
}
class ArtistFactory
{
private $_artists = array();
public function getArtist($name)
{
if(isset($this->_artists[$name]))
{
return $this->_artists[$name];
} else {
$objArtist = new Artist($name);
$this->_artists[$name] = $objArtist;
return $objArtist;
}
}
}
$objArtistFactory = new ArtistFactory();
$objCD1 = new CD();
$objCD1->setTitle("title1");
$objCD1->setArtist($objArtistFactory->getArtist('artist1'));
$objCD2 = new CD();
$objCD2->setTitle("title2");
$objCD2->setArtist($objArtistFactory->getArtist('artist2'));
$objCD3 = new CD();
$objCD3->setTitle("title3");
$objCD3->setArtist($objArtistFactory->getArtist('artist1'));
享元模式的精要有三点:
- 被系统大量使用的细粒度对象,粒度要有多细,量要有多大,看看jdk中使用的享元模式就知道了,jdk中,Integer,Character,String等都使用了享元模式,他们都是最基础的数据类型,不可谓不细,他们频繁的参与运算,不可谓不大量。
- 划分对象的内蕴属性/状态和外蕴属性/状态;所谓内蕴状态,就是存在对象的内部,不会随着环境变化的状态, 有一个网友说的很好,就是无区别的状态, 即拿掉外蕴属性之后同一类对象没有区别对象的内蕴状态就是对象的元神,只要元神元神无区别,那么对象也就无区别,同时也只有这些无区别的元神可以被共享,我想这也是Flyweight被翻译成享元的原因。外蕴状态就是由客户端指定,会随着环境变化的状态; 对于Integer来说, 他的内蕴属性其实就是他的value(当然它也没有外蕴属性);
- 用一个工厂控制享元的创造;因为享元对象不能被客户端随意创造, 否则就没有意义了。工厂通常提供缓存机制保存已经创造的享元。
面向对象虽然很好地解决了抽象性的问题,但是对于一个实际运行的软件系统,我们还需要考虑面向对象的代价问题,享元模式解决的就是面向对象的代价问题。享元模式采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。
享元模式在一般的项目开发中并不常用,而是常常应用于系统底层的开发,以便解决系统的性能问题。Java和.Net中的String类型就是使用了享元模式。如果在Java或者.NET中已经创建了一个字符串对象s1,那么下次再创建相同的字符串s2的时候,系统只是把s2的引用指向s1所引用的具体对象,这就实现了相同字符串在内存中的共享。如果每次执行s1=“abc”操作的时候,都创建一个新的字符串对象的话,那么内存的开销会很大。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。
