您好,登錄后才能下訂單哦!
本文源碼:GitHub·點(diǎn)這里 || GitEE·點(diǎn)這里
應(yīng)用代碼
public class C01_InScene {
public static void main(String[] args) {
String c0 = "cicada" ;
String c1 = "cicada" ;
System.out.println(c0 == c1); // true
}
}
String類(lèi)型就是使用享元模式。String對(duì)象是final類(lèi)型,對(duì)象一旦創(chuàng)建就不可改變。在JAVA中字符串常量都是存在常量池中的,JAVA會(huì)確保一個(gè)字符串常量在常量池中只有一個(gè)拷貝,其中c0和c1就是一個(gè)字符串常量。結(jié)果為:true,說(shuō)明c0和c1兩個(gè)引用都指向了常量池中的同一個(gè)字符串常量"cicada"。這樣的設(shè)計(jì)避免了在創(chuàng)建N多相同對(duì)象時(shí)所產(chǎn)生的不必要的大量的資源消耗。
享元模式是對(duì)象的結(jié)構(gòu)模式。享元模式以共享的方式高效地支持大量的細(xì)粒度對(duì)象。常用于系統(tǒng)底層開(kāi)發(fā),解決系統(tǒng)的性能問(wèn)題。像數(shù)據(jù)庫(kù)連接池,里面都是創(chuàng)建好的連接對(duì)象,在這些連接對(duì)象中有需要的則直接拿來(lái)用,避免重新創(chuàng)建。
給出一個(gè)抽象接口,以規(guī)定具體享元角色要實(shí)現(xiàn)的方法。
實(shí)現(xiàn)抽象享元角色所規(guī)定出的接口。如果有內(nèi)部狀態(tài)的話,必須為內(nèi)部狀態(tài)提供存儲(chǔ)能力。
負(fù)責(zé)創(chuàng)建和管理享元角色。必須保證享元對(duì)象可以被系統(tǒng)選擇性共享。當(dāng)一個(gè)客戶端對(duì)象調(diào)用一個(gè)享元對(duì)象的時(shí)候,享元工廠角色會(huì)檢查系統(tǒng)中是否已經(jīng)有一個(gè)符合要求的享元對(duì)象。如果已經(jīng)存在,直接返回該對(duì)象;如果系統(tǒng)中沒(méi)有該享元對(duì)象,享元工廠角色就應(yīng)當(dāng)創(chuàng)建該享元對(duì)象。
public class C02_FlyWeight {
public static void main(String[] args) {
FlyweightFactory factory = new FlyweightFactory();
Flyweight fly = factory.factoryMethod('c');
fly.printState("One");
fly = factory.factoryMethod('d');
fly.printState("Two");
fly = factory.factoryMethod('c');
fly.printState("San");
// 調(diào)用了三次工廠方法,只創(chuàng)建了兩個(gè)對(duì)象
factory.poolInfo();
}
}
/**
* 抽象享元角色類(lèi)
*/
interface Flyweight {
void printState (String state);
}
/**
* 具體享元角色類(lèi)
*/
class ConcreteFlyweight implements Flyweight {
private Character innerState = null;
public ConcreteFlyweight (Character state){
this.innerState = state;
}
@Override
public void printState(String state) {
System.out.println("內(nèi)部狀態(tài):" + this.innerState);
System.out.println("外部狀態(tài):" + state);
}
}
/**
* 享元工廠角色類(lèi)
*/
class FlyweightFactory {
// 模擬數(shù)據(jù)池
private Map<Character,Flyweight> pool = new HashMap<>();
public Flyweight factoryMethod (Character state){
//先從緩存中查找對(duì)象
Flyweight fly = pool.get(state);
if(fly == null){
fly = new ConcreteFlyweight(state);
pool.put(state, fly);
}
return fly;
}
public void poolInfo (){
System.out.println("數(shù)據(jù)池:"+pool);
}
}
public class C03_Integer {
public static void main(String[] args) {
Integer c1 = Integer.valueOf(127),c2 = Integer.valueOf(127) ;
Integer c3 = new Integer(127),c4 = new Integer(127) ;
boolean flag1 = c1==c2 ,flag2 = c2==c3,flag3 = c3==c4 ;
// true;false;false
System.out.println(flag1+";"+flag2+";"+flag3);
Integer c5 = Integer.valueOf(222),c6=Integer.valueOf(222) ;
// false
System.out.println(c5==c6);
}
}
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
這里valueOf方法的意思就是,如果傳入的數(shù)據(jù)在 (-128) 到 (127) 之間,則從緩存中直接返回,否則創(chuàng)建一個(gè)新的Integer對(duì)象。
享元模式能夠解決重復(fù)對(duì)象的內(nèi)存浪費(fèi)的問(wèn)題,當(dāng)系統(tǒng)中有大量相似對(duì)象,需要緩沖池時(shí)。不需一直創(chuàng)建新對(duì)象,可以從緩沖池里拿。這樣可以降低系統(tǒng)內(nèi)存,同時(shí)提高效率。經(jīng)典的應(yīng)用場(chǎng)景就是池技術(shù),String常量池、數(shù)據(jù)庫(kù)連接池、緩沖池等等都是享元模式的應(yīng)用,享元模式是池技術(shù)的重要實(shí)現(xiàn)方式。享元模式使得系統(tǒng)更加復(fù)雜。為了使對(duì)象可以共享,需要時(shí)刻管理對(duì)象的狀態(tài)變化,這使得程序的邏輯變得復(fù)雜。
GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。