首頁(yè)技術(shù)文章正文

什么是享元模式?享元模式案例教程

更新時(shí)間:2021-08-19 來(lái)源:黑馬程序員 瀏覽量:

IT培訓(xùn)班


運(yùn)用共享技術(shù)來(lái)有效地支持大量細(xì)粒度對(duì)象的復(fù)用。它通過(guò)共享已經(jīng)存在的對(duì)象來(lái)大幅度減少需要?jiǎng)?chuàng)建的對(duì)象數(shù)量、避免大量相似對(duì)象的開銷,從而提高系統(tǒng)資源的利用率。

享元(Flyweight )模式中存在以下兩種狀態(tài):

內(nèi)部狀態(tài),即不會(huì)隨著環(huán)境的改變而改變的可共享部分。

外部狀態(tài),指隨環(huán)境改變而改變的不可以共享的部分。享元模式的實(shí)現(xiàn)要領(lǐng)就是區(qū)分應(yīng)用中的這兩種狀態(tài),并將外部狀態(tài)外部化。


享元模式的主要有以下角色:

抽象享元角色(Flyweight):通常是一個(gè)接口或抽象類,在抽象享元類中聲明了具體享元類公共的方法,這些方法可以向外界提供享元對(duì)象的內(nèi)部數(shù)據(jù)(內(nèi)部狀態(tài)),同時(shí)也可以通過(guò)這些方法來(lái)設(shè)置外部數(shù)據(jù)(外部狀態(tài))。

具體享元(Concrete Flyweight)角色 :它實(shí)現(xiàn)了抽象享元類,稱為享元對(duì)象;在具體享元類中為內(nèi)部狀態(tài)提供了存儲(chǔ)空間。通常我們可以結(jié)合單例模式來(lái)設(shè)計(jì)具體享元類,為每一個(gè)具體享元類提供唯一的享元對(duì)象。

非享元(Unsharable Flyweight)角色 :并不是所有的抽象享元類的子類都需要被共享,不能被共享的子類可設(shè)計(jì)為非共享具體享元類;當(dāng)需要一個(gè)非共享具體享元類的對(duì)象時(shí)可以直接通過(guò)實(shí)例化創(chuàng)建。

享元工廠(Flyweight Factory)角色 :負(fù)責(zé)創(chuàng)建和管理享元角色。當(dāng)客戶對(duì)象請(qǐng)求一個(gè)享元對(duì)象時(shí),享元工廠檢査系統(tǒng)中是否存在符合要求的享元對(duì)象,如果存在則提供給客戶;如果不存在的話,則創(chuàng)建一個(gè)新的享元對(duì)象。



用享元模式實(shí)現(xiàn)俄羅斯方塊游戲功能案例
下面的圖片是眾所周知的俄羅斯方塊中的一個(gè)個(gè)方塊,如果在俄羅斯方塊這個(gè)游戲中,每個(gè)不同的方塊都是一個(gè)實(shí)例對(duì)象,這些對(duì)象就要占用很多的內(nèi)存空間,下面利用享元模式進(jìn)行實(shí)現(xiàn)。

1629361607627_1.jpg

先來(lái)看類圖:

1629361205890_2.png

代碼如下:

俄羅斯方塊有不同的形狀,我們可以對(duì)這些形狀向上抽取出AbstractBox,用來(lái)定義共性的屬性和行為。

public abstract class AbstractBox {
    public abstract String getShape();

    public void display(String color) {
        System.out.println("方塊形狀:" + this.getShape() + " 顏色:" + color);
    }
}

接下來(lái)就是定義不同的形狀了,IBox類、LBox類、OBox類等。

public class IBox extends AbstractBox {

    @Override
    public String getShape() {
        return "I";
    }
}

public class LBox extends AbstractBox {

    @Override
    public String getShape() {
        return "L";
    }
}

public class OBox extends AbstractBox {

    @Override
    public String getShape() {
        return "O";
    }
}

提供了一個(gè)工廠類(BoxFactory),用來(lái)管理享元對(duì)象(也就是AbstractBox子類對(duì)象),該工廠類對(duì)象只需要一個(gè),所以可以使用單例模式。并給工廠類提供一個(gè)獲取形狀的方法。

public class BoxFactory {

    private static HashMap<String, AbstractBox> map;

    private BoxFactory() {
        map = new HashMap<String, AbstractBox>();
        AbstractBox iBox = new IBox();
        AbstractBox lBox = new LBox();
        AbstractBox oBox = new OBox();
        map.put("I", iBox);
        map.put("L", lBox);
        map.put("O", oBox);
    }

    public static final BoxFactory getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder {
        private static final BoxFactory INSTANCE = new BoxFactory();
    }

    public AbstractBox getBox(String key) {
        return map.get(key);
    }
}






猜你喜歡:

if結(jié)構(gòu)語(yǔ)句的格式有幾種?應(yīng)該怎樣執(zhí)行操作?

Java進(jìn)階教程:treemap數(shù)據(jù)結(jié)構(gòu)視頻教程

設(shè)計(jì)模式是什么?有哪些分類?

黑馬程序員Java開發(fā)培訓(xùn)課程

分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!