購物網(wǎng)站設(shè)計(jì)開題報(bào)告微商軟文范例大全100
享元模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,主要通過共享技術(shù)有效地減少大量細(xì)粒度對象的復(fù)用,以減少內(nèi)存占用和提高性能。由于享元模式要求能夠共享的對象必須是細(xì)粒度對象,因此它又稱為輕量級模式。
Flyweight is a structural pattern, which effectively reduces the reuse of a large number of fine-grained objects through sharing technology to reduce memory consumption and improve performance. Since the flyweight pattern requires that objects that can be shared must be fine-grained objects, it is also called lightweight mode.
結(jié)構(gòu)設(shè)計(jì)
Flyweight: 抽象享元類,包含原始對象中部分能在多個(gè)對象中共享的狀態(tài)。 同一享元對象可在許多不同情景中使用。 享元中存儲的狀態(tài)被稱為 “內(nèi)在狀態(tài)”。 傳遞給享元方法的狀態(tài)被稱為 “外在狀態(tài)”。
ConcreteFlyweight: 具體享元類,實(shí)現(xiàn)享元接口,并為內(nèi)部狀態(tài)(如果存在的話)增加存儲空間。
UnsharedConcreteFlyweight: 非共享具體享元類,抽象享元類使共享成為可能,但并不強(qiáng)制共享。
FlyweightFactory: 享元工廠類, 享元工廠會對已有享元的緩存池進(jìn)行管理。 有了工廠后, 客戶端就無需直接創(chuàng)建享元, 它們只需調(diào)用工廠并向其傳遞目標(biāo)享元的一些內(nèi)在狀態(tài)即可。 工廠會根據(jù)參數(shù)在之前已創(chuàng)建的享元中進(jìn)行查找, 如果找到滿足條件的享元就將其返回; 如果沒有找到就根據(jù)參數(shù)新建享元。
享元模式類圖表示如下:
偽代碼實(shí)現(xiàn)
接下來將使用代碼介紹下享元模式的實(shí)現(xiàn)。
// 1、抽象享元類,存儲的狀態(tài)被稱為 "內(nèi)在狀態(tài)"。 傳遞給享元方法的狀態(tài)被稱為 "外在狀態(tài)"
public abstract class Flyweight {private String intrinsic;protected String extrinsic;public Flyweight(String extrinsic) {this.extrinsic = extrinsic;}public abstract void operation(String extrinsic);
}
// 2、具體享元類,實(shí)現(xiàn)享元接口
public class ConcreteFlyweight extends Flyweight {public ConcreteFlyweight(String extrinsic) {super(extrinsic);}@Overridepublic void operation(String extrinsic) {System.out.println("do some thing in the concrete flyweight instance");}
}
// 3、非共享具體享元類,抽象享元類使共享成為可能,但并不強(qiáng)制共享
public class UnsharedConcreteFlyweight extends Flyweight {public UnsharedConcreteFlyweight(String extrinsic) {super(extrinsic);}@Overridepublic void operation(String extrinsic) {System.out.println("do some thing in the unshared concrete flyweight instance");}
}
// 4、享元工廠類, 享元工廠會對已有享元的緩存池進(jìn)行管理。 有了工廠后, 客戶端就無需直接創(chuàng)建享元,
// 它們只需調(diào)用工廠并向其傳遞目標(biāo)享元的一些狀態(tài)即可
public class FlyweightFactory {private static final Map<String, Flyweight> pool = new HashMap<>();public static Flyweight getFlyweight(String extrinsic) {Flyweight flyweight = pool.get(extrinsic);if (flyweight == null) {flyweight = new ConcreteFlyweight(extrinsic);pool.put(extrinsic, flyweight);System.out.println("put a fly weight instance to the pool");}return flyweight;}
}
// 5、客戶端調(diào)用
public class FlyweightClient {public void test() {// 從享元工廠獲取享元類Flyweight flyweight1 = FlyweightFactory.getFlyweight("one");// 執(zhí)行享元方法flyweight1.operation("one");// 從享元工廠獲取重復(fù)享元類(直接從緩存池獲取)Flyweight flyweight2 = FlyweightFactory.getFlyweight("one");flyweight2.operation("one");// 獲取非共享享元子類Flyweight unsharedConcreteFlyweight = new UnsharedConcreteFlyweight("two");unsharedConcreteFlyweight.operation("two");}
}
適用場景
在以下情況下可以考慮使用享元模式:
(1) 一個(gè)系統(tǒng)有大量相同或者相似的對象,由于這類對象的大量使用,造成內(nèi)存的大量耗費(fèi)。
應(yīng)用該模式所獲的收益大小取決于使用它的方式和情景。它在下列情況中最有效:
程序需要生成數(shù)量巨大的相似對象
這將耗盡目標(biāo)設(shè)備的所有內(nèi)存
對象中包含可抽取且能在多個(gè)對象間共享的重復(fù)狀態(tài)
(2) 對象的大部分狀態(tài)都可以外部化,可以將這些外部狀態(tài)傳入對象中。
使用享元模式需要維護(hù)一個(gè)存儲享元對象的享元池,而這需要耗費(fèi)資源,因此,應(yīng)當(dāng)在多次重復(fù)使用享元對象時(shí)才值得使用享元模式。
優(yōu)缺點(diǎn)
享元模式有以下優(yōu)點(diǎn):
(1) 節(jié)省內(nèi)存。享元模式的優(yōu)點(diǎn)在于它可以極大減少內(nèi)存中對象的數(shù)量,使得相同對象或相似對象在內(nèi)存中只保存一份。如果程序中有很多相似對象,那么可以考慮使用該模式
(2) 享元模式的外部狀態(tài)相對獨(dú)立,而且不會影響其內(nèi)部狀態(tài),從而使得享元對象可以在不同的環(huán)境中被共享
但是享元模式也存在以下缺點(diǎn):
(1) 可能需要犧牲執(zhí)行速度來換取內(nèi)存,為了使對象可以共享,享元模式需要將享元對象的狀態(tài)外部化,而讀取外部狀態(tài)使得運(yùn)行時(shí)間變長。
(2) 代碼會變得更加復(fù)雜。 需要分離出內(nèi)部狀態(tài)和外部狀態(tài),這使得程序的邏輯復(fù)雜化
參考
《設(shè)計(jì)模式 可復(fù)用面向?qū)ο筌浖幕A(chǔ)》 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著, 李英軍, 馬曉星等譯
https://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/flyweight.html 享元模式
https://refactoringguru.cn/design-patterns/flyweight 享元模式
https://www.runoob.com/design-pattern/flyweight-pattern.html 享元模式
https://www.cnblogs.com/adamjwh/p/9070107.html 簡說設(shè)計(jì)模式——享元模式
https://blog.csdn.net/ShuSheng0007/article/details/116424138 秒懂設(shè)計(jì)模式之享元模式