成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

一起學(xué)設(shè)計(jì)模式 - 享元模式

Jason / 1904人閱讀

摘要:享元模式屬于結(jié)構(gòu)型模式的一種,又稱輕量級(jí)模式,通過(guò)共享技術(shù)有效地實(shí)現(xiàn)了大量細(xì)粒度對(duì)象的復(fù)用概述兩種結(jié)構(gòu)狀態(tài)內(nèi)部狀態(tài)享元對(duì)象內(nèi)部不隨外界環(huán)境改變而改變的共享部分。

享元模式(Flyweight Pattern)屬于結(jié)構(gòu)型模式的一種,又稱輕量級(jí)模式,通過(guò)共享技術(shù)有效地實(shí)現(xiàn)了大量細(xì)粒度對(duì)象的復(fù)用...

概述

兩種結(jié)構(gòu)狀態(tài)

內(nèi)部狀態(tài):享元對(duì)象內(nèi)部不隨外界環(huán)境改變而改變的共享部分。

外部狀態(tài):享元對(duì)象內(nèi)部環(huán)境的改變而改變,不能夠共享的狀態(tài)就是外部狀態(tài)。

結(jié)構(gòu)圖

存在的角色

Flyweight(抽象享元類):通常是一個(gè)接口或抽象類,向外界提供享元對(duì)象的內(nèi)部數(shù)據(jù)(內(nèi)部狀態(tài))或外部數(shù)據(jù)(外部狀態(tài))。

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

UnsharedConcreteFlyweight(非共享具體享元類):指不需要共享的Flyweight子類。

FlyweightFactory(享元工廠類):用于創(chuàng)建并管理享元對(duì)象,針對(duì)抽象享元類編程,將各種類型的具體享元對(duì)象存儲(chǔ)在一個(gè)享元池中,享元池一般設(shè)計(jì)為鍵值對(duì)的集合(也可以是其他類型的集合),同時(shí)可以結(jié)合工廠模式進(jìn)行設(shè)計(jì)。

享元模式的核心在于享元工廠類,享元工廠類的作用在于提供一個(gè)用于存儲(chǔ)享元對(duì)象的享元池,用戶需要對(duì)象時(shí),首先從享元池中獲取,如果享元池中不存在,則創(chuàng)建一個(gè)新的享元對(duì)象返回給用戶,并在享元池中保存該新增對(duì)象。

案例

案例UML圖如下:

1.創(chuàng)建Flyweight接口/抽象類

interface Flyweight {
    void operation(String name);

    String getType();
}

2.創(chuàng)建ConcreteFlyweight(享元對(duì)象),實(shí)現(xiàn)了Flyweight接口

class ConcreteFlyweight implements Flyweight {
    private String type;

    public ConcreteFlyweight(String type) {
        this.type = type;
    }

    @Override
    public void operation(String name) {
        System.out.printf("[類型(內(nèi)在狀態(tài))] - [%s] - [名字(外在狀態(tài))] - [%s]
", type, name);
    }

    @Override
    public String getType() {
        return type;
    }
}

3.創(chuàng)建FlyweightFactory(享元工廠類),用來(lái)維護(hù)享元池

class FlyweightFactory {
    private static final Map FLYWEIGHT_MAP = new HashMap<>();

    public static Flyweight getFlyweight(String type) {
        if (FLYWEIGHT_MAP.containsKey(type)) {
            return FLYWEIGHT_MAP.get(type);
        } else {
            ConcreteFlyweight flyweight = new ConcreteFlyweight(type);
            FLYWEIGHT_MAP.put(type, flyweight);
            return flyweight;
        }
    }

    public static int total() {
        return FLYWEIGHT_MAP.size();
    }
}

4.創(chuàng)建Client(測(cè)試類)

public class Client {

    public static void main(String[] args) {
        Flyweight fw0 = FlyweightFactory.getFlyweight("戰(zhàn)士");
        Flyweight fw1 = FlyweightFactory.getFlyweight("戰(zhàn)士");
        Flyweight fw2 = FlyweightFactory.getFlyweight("法師");
        Flyweight fw3 = FlyweightFactory.getFlyweight("坦克");
        fw1.operation("瑞文");
        fw1.operation("鱷魚(yú)");
        fw2.operation("光輝");
        fw3.operation("泰坦");
        fw3.operation("蓋倫");
        System.out.printf("[結(jié)果(對(duì)象對(duì)比)] - [%s]
", fw0 == fw1);
        System.out.printf("[結(jié)果(內(nèi)在狀態(tài))] - [%s]
", fw1.getType());
        System.out.printf("一共召喚 %s 種類型英雄
", FlyweightFactory.total());
    }
}

5.運(yùn)行結(jié)果,從結(jié)果中可以發(fā)現(xiàn),只生成了3個(gè)不同的類

[類型(內(nèi)在狀態(tài))] - [戰(zhàn)士] - [名字(外在狀態(tài))] - [瑞文]
[類型(內(nèi)在狀態(tài))] - [戰(zhàn)士] - [名字(外在狀態(tài))] - [鱷魚(yú)]
[類型(內(nèi)在狀態(tài))] - [法師] - [名字(外在狀態(tài))] - [光輝]
[類型(內(nèi)在狀態(tài))] - [坦克] - [名字(外在狀態(tài))] - [泰坦]
[類型(內(nèi)在狀態(tài))] - [坦克] - [名字(外在狀態(tài))] - [蓋倫]
[結(jié)果(對(duì)象對(duì)比)] - [true]
[結(jié)果(內(nèi)在狀態(tài))] - [戰(zhàn)士]
一共召喚 3 種類型英雄
JDK中使用

在JAVA語(yǔ)言中,String類型就是使用了享元模式。String對(duì)象是final類型,對(duì)象一旦創(chuàng)建就不可改變。在JAVA中字符串常量都是存在常量池中的,JAVA會(huì)確保一個(gè)字符串常量在常量池中只有一個(gè)拷貝。

public class Client {
    public static void main(String[] args) {
        String a = "蓋倫";
        String b = "蓋倫";
        System.out.println(a==b);// 返回 true
    }
}

上面的例子中結(jié)果為:true,這就說(shuō)明a和b兩個(gè)引用都指向了常量池中的同一個(gè)字符串常量。這樣設(shè)計(jì)的目的就是:為了避免在創(chuàng)建多相同對(duì)象時(shí),所產(chǎn)生的不必要的資源消耗。

總結(jié)

如果程序里使用大量相同或者相似的對(duì)象,造成內(nèi)存的大量耗費(fèi),且大多都是外部狀態(tài),這時(shí)候就應(yīng)該考慮使用享元模式了,比如圍棋、五子棋等小游戲

優(yōu)點(diǎn)

能夠極大的減少系統(tǒng)中對(duì)象的個(gè)數(shù)。

外部狀態(tài)相對(duì)獨(dú)立,不會(huì)影響到內(nèi)部狀態(tài),能夠使享元對(duì)象在不同的環(huán)境被共享。

缺點(diǎn)

由于享元模式需要區(qū)分外部狀態(tài)和內(nèi)部狀態(tài),使得程序在某種程度上來(lái)說(shuō)更加復(fù)雜化了。

為了使對(duì)象可以共享,享元模式需要將享元對(duì)象的狀態(tài)外部化,而讀取外部狀態(tài)使得運(yùn)行時(shí)間變長(zhǎng)。

- 說(shuō)點(diǎn)什么

全文代碼:https://gitee.com/battcn/design-pattern/tree/master/Chapter9/battcn-flyweight

個(gè)人QQ:1837307557

battcn開(kāi)源群(適合新手):391619659

微信公眾號(hào):battcn(歡迎調(diào)戲)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/68022.html

相關(guān)文章

  • 設(shè)計(jì)模式》3.結(jié)構(gòu)型模式

    摘要:類的適配器結(jié)構(gòu)目標(biāo)角色這就是所期待得到的接口,由于是類適配器模式,因此目標(biāo)不可以是類。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它是作為現(xiàn)有的類的一個(gè)包裝。和適配器模式的關(guān)系適配器模式的用意是改變所考慮對(duì)象的接口,而代理模式不能改變。 點(diǎn)擊進(jìn)入我的博客 3.1 適配器模式 適配器模式把一個(gè)類的接口變換成客戶端所期待的另一種接口,使得原本因接口不匹配而無(wú)法在一起工作的兩個(gè)類能夠在一起工作。 3...

    Yuqi 評(píng)論0 收藏0
  • 設(shè)計(jì)模式在jdk中的應(yīng)用

    摘要:本文只是尋找設(shè)計(jì)模式在中的應(yīng)用。來(lái)補(bǔ)全這一塊工廠模式中的應(yīng)用包線程池解釋和代碼線程池中有線程創(chuàng)建工廠。狀態(tài)模式中的應(yīng)用解釋和代碼根據(jù)一個(gè)指針的狀態(tài)而改變自己的行為適配器模式中的應(yīng)用解釋和代碼將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。 前言 最近重學(xué)設(shè)計(jì)模式,而且還有很多源碼要看。所以就想一舉兩得。從源碼中尋找設(shè)計(jì)模式。順便還可以看看源碼。。。本文只是尋找設(shè)計(jì)模式在java中的應(yīng)用。優(yōu)...

    dingding199389 評(píng)論0 收藏0
  • “大話”設(shè)計(jì)模式

    摘要:抽象工廠模式是為了處理對(duì)象具有等級(jí)結(jié)構(gòu)以及對(duì)象族的問(wèn)題。單例設(shè)計(jì)模式單例模式確保某一個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例,這個(gè)類成為單例類。 導(dǎo)語(yǔ):設(shè)計(jì)模式是無(wú)數(shù)碼農(nóng)前人在實(shí)際的生產(chǎn)項(xiàng)目中經(jīng)過(guò)不斷的踩坑、爬坑、修坑的經(jīng)歷總結(jié)出來(lái)的經(jīng)驗(yàn)教訓(xùn),經(jīng)過(guò)抽象之后表達(dá)成的概念。能夠幫助后來(lái)的設(shè)計(jì)者避免重復(fù)同樣的錯(cuò)誤或者彎路。我也抽空整理了一下設(shè)計(jì)模式,用自己的話總結(jié)了一下,自認(rèn)...

    coordinate35 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<