目錄
一、基本概念
二、UML類圖
三、角色設計
四、案例分析
4.1、基本實現(xiàn)
4.2、游戲角色
五、總結
一、基本概念
享元模式是一種結構型設計模式,主要用于減少創(chuàng)建大量相似對象所占用的內(nèi)存,它通過共享技術來有效支持大量細粒度的對象。
二、UML類圖
三、角色設計
角色 | 描述 |
---|---|
抽象享元角色 | 定義出對象的外部狀態(tài)和內(nèi)部狀態(tài)的接口或屬性。 |
具體享元角色 | 實現(xiàn)抽象享元角色,定義內(nèi)部狀態(tài),可以保存共享對象的狀態(tài) |
享元工廠角色 | 負責創(chuàng)建和管理享元對象 |
客戶端角色 | 存儲外部狀態(tài),在需要時通過享元工廠獲取享元對象 |
四、案例分析
享元模式中的享元對象可以認為是一種可復用的組件。比如在游戲中,有許多類型相同的敵人,這時就可以使用享元模式。
1、我們會創(chuàng)建一個享元工廠類,這個類就像一個存放享元對象的倉庫??蛻舳诵枰獙ο髸r,就來這個工廠類這里取。
2、工廠類存放的是享元對象。享元對象有兩種狀態(tài):內(nèi)部狀態(tài)與外部狀態(tài)。
內(nèi)部狀態(tài)是對象共享的部分,不會改變,比如敵人的形狀、顏色等。
外部狀態(tài)是對象依賴的可變部分,比如敵人的位置。
3、當客戶端需要一個享元對象時,會先從工廠請求。?
如果工廠里已有該對象,就直接返回已有實例,復用該對象。?
如果沒有,則創(chuàng)建新實例,并存入工廠后返回。
4、客戶端拿到對象后,將外部狀態(tài)設置給該對象,然后顯示。
5、對象使用完后并不銷毀,而是返還給工廠繼續(xù)復用。這樣通過管理可復用的享元對象,就可以大量減少對象的創(chuàng)建,節(jié)省內(nèi)存空間,提高性能。
本篇共舉了2個簡單的小案例進行分析,可以更好的去理解這個設計模式。
4.1、基本實現(xiàn)
首先定義一個享元接口并聲明了一個操作方法:
interface Flyweight {
void operate(String extrinsicState);
}
創(chuàng)建具體的享元類,實現(xiàn)享元接口,并包含內(nèi)部狀態(tài):?
class ConcreteFlyweight implements Flyweight {
private String intrinsicState;
public ConcreteFlyweight(String intrinsicState) {
this.intrinsicState = intrinsicState;
}
public void operate(String extrinsicState) {
System.out.println("內(nèi)部狀態(tài): " + intrinsicState);
System.out.println("外部狀態(tài): " + extrinsicState);
// 執(zhí)行享元操作
}
}
創(chuàng)建享元工廠類,用于管理和共享享元對象:?
import java.util.HashMap;
import java.util.Map;
class FlyweightFactory {
private Map<String, Flyweight> flyweights;
public FlyweightFactory() {
flyweights = new HashMap<>();
}
public Flyweight getFlyweight(String intrinsicState) {
if (flyweights.containsKey(intrinsicState)) {
return flyweights.get(intrinsicState);
} else {
Flyweight flyweight = new ConcreteFlyweight(intrinsicState);
flyweights.put(intrinsicState, flyweight);
return flyweight;
}
}
}
在客戶端中使用享元工廠類來獲取和使用享元對象:
public class Client {
public static void main(String[] args) {
FlyweightFactory factory = new FlyweightFactory();
// 獲取或創(chuàng)建享元對象
Flyweight flyweight1 = factory.getFlyweight("SharedState");
Flyweight flyweight2 = factory.getFlyweight("SharedState");
// 使用享元對象
flyweight1.operate("ExtrinsicState1");
flyweight2.operate("ExtrinsicState2");
}
}
運行結果如下:
4.2、游戲角色
我們舉一個形象一些的例子,游戲中需要顯示大量的相似的敵人角色,這時就可以使用享元模式復用對象以減少內(nèi)存開銷。
定義角色(抽象享元角色)接口:
public interface GameRole {
void display(String name);
}
具體角色(具體享元角色)實現(xiàn):
public class Enemy implements GameRole {
private String type;
public Enemy(String type){
this.type = type;
}
@Override
public void display(String attackType) {
System.out.println(type+"敵人已啟用!"+"攻擊方式:"+attackType);
}
}
角色工廠(享元工廠角色)實現(xiàn):
import java.util.HashMap;
import java.util.Map;
public class RoleFactory {
private Map<String, GameRole> pool;
public RoleFactory() {
pool = new HashMap<>();
}
GameRole getRole(String type) {
if(!pool.containsKey(type)) {
pool.put(type, new Enemy(type));
}
return pool.get(type);
}
}
客戶端:
public class Client {
public static void main(String[] args) {
RoleFactory factory = new RoleFactory();
GameRole a = factory.getRole("A");
GameRole b = factory.getRole("B");
a.display("boom");
b.display("fly");
}
}
運行結果如下:
五、總結
優(yōu)點:
1、減少內(nèi)存占用,降低系統(tǒng)資源消耗。
2、提高系統(tǒng)性能。
缺點:
1、增加了系統(tǒng)的復雜度;
2、區(qū)分內(nèi)部狀態(tài)和外部狀態(tài)可能會很復雜;
3、享元模式使得系統(tǒng)難以維護和擴展。
應用場景:
1、一個應用程序使用大量的相似對象。
2、對象的大多數(shù)狀態(tài)都可以外部化。
3、在內(nèi)存是關鍵資源的系統(tǒng)中。
4、系統(tǒng)要求消除大量相似類的重復對象。
例如游戲設計中復用相同的角色對象、網(wǎng)站設計的外觀樣式、多線程池中的線程對象等都適合使用享元模式。
符合的設計原則:
1、單一職責原則(Single Responsibility Principle)
享元模式分離了內(nèi)部狀態(tài)和外部狀態(tài)。
2、開閉原則(Open Close Principle)
新增享元對象不影響其他對象。
3、組合復用原則(Composite Reuse Principle)文章來源:http://www.zghlxwxcb.cn/news/detail-570765.html
享元對象可以被組合、聚合。文章來源地址http://www.zghlxwxcb.cn/news/detail-570765.html
到了這里,關于Java設計模式之結構型-享元模式(UML類圖+案例分析)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!