博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式之享元模式
阅读量:7282 次
发布时间:2019-06-30

本文共 2891 字,大约阅读时间需要 9 分钟。

享元模式(FlyWeight)

  享元模式是设计模式中少数几个以提高系统性能为目的的设计模式。他的核心思想是:如果一个系统中存在多个相同的对象,那么只需共享一份对象的拷贝,而不必为每一次使用都创建新的对象。

  在享元模式中,由于需要构造和维护这些可以共享的对象,因此需要一个工厂类用于维护和创建共享对象。

享元模式实现

  • FlyWeightFactory享元工厂类
    • 创建并管理享元对象,享元池一般设计成键值对,即用Map存储
  • FlyWeight:抽象享元类
    • 通常是一个接口或者抽象类,声明公开的方法,这些方法可以向外界提供对象的内部状态,设置外部状态
  • ConcreteFlyWeight:具体享元类
    • 为内部状态提供成员变量进行存储
  • UnSharedConcreteFlyWeight:非共享享元类
    • 不能被共享的子类可以设计为非共享享元类

举例说明

  如果需要做一款扑克牌游戏(不考虑大小王),扑克总共52张,我们平时可能考虑创建52个不同的对象即可。但是可以发现,这些扑克牌不就是分为四类(红桃:Heart;黑桃:Spade;方块:Diamond;梅花:Club),每类不同的就是牌面A-K。

  用享元模式设计如下:

  (1)枚举定义扑克类型

/** * CardType 扑克牌类型 * @author yangkj */public enum CardType {    //红桃:Heart;黑桃:Spade;方块:Diamond;梅花:Club    HEART,SPADE,DIAMOND,CLUB}

  (2)非共享享元类(这里当然就是牌面)

/** * CardBasic 扑克牌牌面 * @author yangkj*/public class CardBasic {    /**     * 牌面值     */    private String numbber;    public String getNumbber() {        return numbber;    }    public void setNumbber(String numbber) {        this.numbber = numbber;    }    public CardBasic(String numbber) {        super();        this.numbber = numbber;    }    public CardBasic() {        super();    }}

   (3)抽象享元接口 及 具体享元类

/** * Card 抽象享元接口 * @author yangkj*/public interface Card {
void display(CardBasic basic);}/** * CardEntity 具体享元类 * @author yangkj */class CardEntity implements Card { // 共享的属性 private CardType type; @Override public void display(CardBasic basic) { System.out.println("扑克牌花色:"+type); System.out.println("扑克牌牌面:"+basic.getNumbber()); } public CardEntity(CardType type) { super(); this.type = type; }}

  (4)享元工厂类

/** * CardFactory 享元工厂类 * @author yangkj*/public class CardFactory {    private static Map
map = new HashMap<>(); public static Card getCardInstance(CardType type){ if(null !=map.get(type)){ return map.get(type); }else{ Card card = new CardEntity(type); map.put(type.name(), card); return card; } }}

  (5)测试类

public static void main(String[] args) {        /**         * 创建四种扑克牌花色(共享享元实体)         */        Card cardHeart = CardFactory.getCardInstance(CardType.HEART);        Card cardClub = CardFactory.getCardInstance(CardType.CLUB);        Card cardDiamond = CardFactory.getCardInstance(CardType.DIAMOND);        Card cardSpade = CardFactory.getCardInstance(CardType.SPADE);        /**         * 创建扑克牌牌面(非共享享元)         */        CardBasic basic8 = new CardBasic("8");        CardBasic basic10 = new CardBasic("10");        /**         * 组装         */        cardHeart.display(basic8);        cardDiamond.display(basic8);        cardClub.display(basic10);        cardSpade.display(basic10);    }

  (6)测试结果

  

享元模式应用场景

  1. 享元模式由于其共享的特性,可以用于”池“,如线程池、数据库连接池
  2. String类的设计也是享元模式,我们知道String内容是存放在常量池中

享元模式优缺点

  • 优点
    • 极大减少内存中对象的数量
    • 相同或相似对象在内存中只存一份,极大节约内存资源,提高了系统性能
    • 外部状态相对独立,不影响内部状态
  • 缺点
    • 模式较复杂,会使得程序逻辑变得复杂
    • 为了节省类存,共享了内部状态,分离出外部状态,而读取外部状态使得运行时间变长,用时间换空间

 

 

  

  

转载地址:http://xnkjm.baihongyu.com/

你可能感兴趣的文章
JavaScript Array 对象
查看>>
DGX Station助力肺结节的智能分析诊断
查看>>
Debian下怎样以不同颜色显示不同的文件或目录
查看>>
用C#进行CCITT校验函数
查看>>
数据库安装完成后,必改系统参数之一
查看>>
php的介绍
查看>>
Linux下搭建MySQL的主从复制(一)
查看>>
第十节:python异常处理、类
查看>>
hive基本操作
查看>>
20171226-Win10英文版系统显示中文乱码的解决方案
查看>>
RHEL6 64位ASM方式安装oracle 11gR2(一)
查看>>
apt-get和pkgsrc
查看>>
意外断电造成RAID 5阵列卡数据故障的恢复方法
查看>>
使用Xshell密钥认证机制远程登录Linux
查看>>
A new node couldn't be inserted because one with the same name exists. (VERR_CFGM_NODE_EXISTS).
查看>>
您真的会玩KMS吗_03.排错篇
查看>>
bootstrap,jquery利用后台传入的json数据创建动态表格
查看>>
Azure 中国篇之应用服务--Azure目录同步
查看>>
golang在window环境下用cgo编译c语言
查看>>
在 CentOS 5.0 中安装 RPMforge 安装源
查看>>