JDK中的设计模式之享元模式

一、享元模式概述

    享元模式的意图是运用共享技术有效地支持大量细粒度的对象,它适合用于当大量物件只是重复因而导致无法令人接受的使用大量内存时。通常物件中的部分状态是可以分享,常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。

        享元模式适用于:1、一个应用程序使用了大量的对象;2、完全由于使用大量的对象,造成很大的内存开销;3、对象的大多数状态都可变为外部状态;4、应用程序不依赖于对象标识。

        享元模式结构图如下:



      结构对象说明:

     1:抽象享元角色(Flyweight):此角色是所有的具体享元类的超类,为这些类规定出需要实现的公共接口。那些需要外蕴状态的操作可以通过方法的参数传入。抽象享元的接口使得享元变得可能,但是并不强制子类实行共享,因此并非所有的享元对象都是可以共享的。

    2:具体享元(ConcreteFlyweight)角色:实现抽象享元角色所规定的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。享元对象的内蕴状态必须与对象所处的周围环境无关,从而使得享元对象可以在系统内共享。有时候具体享元角色又叫做单纯具体享元角色,因为复合享元角色是由单纯具体享元角色通过复合而成的。


    3:复合享元(UnsharableFlyweight)角色:复合享元角色所代表的对象是不可以共享的,但是一个复合享元对象可以分解成为多个本身是单纯享元对象的组合。复合享元角色又称做不可共享的享元对象。


    4:享元工厂(FlyweightFactoiy)角色:本角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象请求一个享元对象的时候,享元工厂角色需要检查系统中是否已经有一个符合要求的享元对象,如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个新的合适的享元对象。


    5:客户端(Client)角色:本角色还需要自行存储所有享元对象的外蕴状态。


二、JDK中的享元模式

    JDK中使用了享元模式的类是java.lang.Integer,该类有方法valueOf(int),在实现上当内存中已经有一个相同数字的包装器时,这个方法不会构造一个新的包装器,而是返回现成的包装器,使得两个变量共享同一个数字包装器对象。所以即使调用了上万次valueOf同一个数字并分别赋给了不同的变量,内存中也只有一个包装器对象存在。


在JDK中使用享元模式的类还有String类。如果在Java中已经创建了一个字符串对象s1,那么下次再创建相同的字符串s2的时候,系统只是把s2的引用指向s1所引用的具体对象,这就实现了相同字符串在内存中的共享。如果每次执行s1=“abc”操作的时候,都创建一个新的字符串对象的话,那么内存的开销会很大。

如果大家有兴趣的话,可以用下面的程序进行测试,就会知道s1和s2的引用是否一致:

String s1 = "测试字符串1";
String s2 = "测试字符串1";
//“==”用来判断两个对象是否是同一个,equals判断字符串的值是否相等
if( s1 == s2 ){
System.out.println("两者一致");
}else{
System.out.println("两者不一致");
}

输出为两者一致,说明String使用到了享元模式。


三、关于享元模式的思考

        事物总有两面性,享元模式既有优点,也有缺点。享元模式的优点是大幅度地降低内存中对象的数量。 享元模式的缺点是 1:享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。2:享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。总的来说,享元模式一般是解决系统性能问题的,所以经常用于底层开发,在项目开发中并不常用。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值