Java设计模式系列-享元模式(结构型)
一、概述
享元模式:“享”就是分享之意,指一物被众人共享,而这也正是该模式的终旨所在。
享元模式有点类似于单例模式,都是只生成一个对象来被共享使用。这里有个问题,那就是对共享对象的修改,为了避免出现这种情况,我们将这些对象的公共部分,或者说是不变化的部分抽取出来形成一个对象。这个对象就可以避免到修改的问题。
享元的目的是为了减少不会要额内存消耗,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的对象,以此来降低内存的消耗。
二、示例
下面我们来看一个简单的例子:
建筑接口:JianZhu
public interface Jianzhu { void use(); }
体育馆实现类:TiYuGuan
public class TiYuGuan implements Jianzhu { private String name; private String shape; private String yundong; public TiYuGuan(String yundong){ this.setYundong(yundong); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getShape() { return shape; } public void setShape(String shape) { this.shape = shape; } public String getYundong() { return yundong; } public void setYundong(String yundong) { this.yundong = yundong; } @Override public void use() { System.out.println("该体育馆被使用来召开奥运会" + " 运动为:"+ yundong+" 形状为:"+shape+ " 名称为:"+name); } }
建筑工厂类:JianZhuFactory
import java.util.*; public class JianZhuFactory { private static final Map<String,TiYuGuan> tygs = new HashMap<String,TiYuGuan>(); public static TiYuGuan getTyg(String yundong){ TiYuGuan tyg = tygs.get(yundong); if(tyg == null){ tyg = new TiYuGuan(yundong); tygs.put(yundong,tyg); } return tyg; } public static int getSize(){ return tygs.size(); } }
测试类:Clienter
public class Clienter { public static void main(String[] args) { String yundong ="足球"; for(int i = 1;i <= 5;i++){ TiYuGuan tyg = JianZhuFactory.getTyg(yundong); tyg.setName("中国体育馆"); tyg.setShape("圆形"); tyg.use(); System.out.println("对象池中对象数量为:"+JianZhuFactory.getSize()); } } }
执行结果:
该体育馆被使用来召开奥运会 运动为:足球 形状为:圆形 名称为:中国体育馆 对象池中对象数量为:1 该体育馆被使用来召开奥运会 运动为:足球 形状为:圆形 名称为:中国体育馆 对象池中对象数量为:1 该体育馆被使用来召开奥运会 运动为:足球 形状为:圆形 名称为:中国体育馆 对象池中对象数量为:1 该体育馆被使用来召开奥运会 运动为:足球 形状为:圆形 名称为:中国体育馆 对象池中对象数量为:1 该体育馆被使用来召开奥运会 运动为:足球 形状为:圆形 名称为:中国体育馆 对象池中对象数量为:1
三、模式解析
如上示例中,使用工厂模式进行配合,创建对象池,测试类中的循环,你可以想象成为要举行5场比赛,每场比赛的场地就是体育馆
通过执行结果可以看出,在这个对象池(HashMap)中,一直都只有一个对象存在,第一次使用的时候创建对象,之后的每次调用都用的是那个对象,不会再重新创建。
其实在Java中就存在这种类型的实例:String。
Java中将String类定义为final(不可改变的),JVM中字符串一般保存在字符串常量池中,这个字符串常量池在jdk 6.0以前是位于常量池中,位于永久代,而在JDK 7.0中,JVM将其从永久代拿出来放置于堆中。
我们使用如下代码定义的两个字符串指向的其实是同一个字符串常量池中的字符串值。
String s1 = "abc"; String s2 = "abc";
如果我们以s1==s2进行比较的话所得结果为:true,因为s1和s2保存的是字符串常量池中的同一个字符串地址。这就类似于我们今天所讲述的享元模式,字符串一旦定义之后就可以被共享使用,因为他们是不可改变的,同时被多处调用也不会存在任何隐患。
四、使用场景
当我们项目中创建很多对象,而且这些对象存在许多相同模块,这时,我们可以将这些相同的模块提取出来采用享元模式生成单一对象,再使用这个对象与之前的诸多对象进行配合使用,这样无疑会节省很多空间。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
容器服务&&AHAS Sentinel 弹性 Demo
应用高可用服务 AHAS(Application High Availability Service)是一款阿里云应用高可用服务相关产品。只要容器服务中的 Java 应用接入了 AHAS 应用流控组件后,用户的应用实例就可以自动根据 AHAS Sentinel 收集的指标(如 QPS、平均响应时间等)进行弹性伸缩,使得系统可以自动根据实时的流量情况进行扩缩容,保证系统的可用性。 0. 安装 alibaba-cloud-metrics-adapter 可以直接在容器服务控制台 应用目录 中安装 alibaba-cloud-metrics-adapter。 相关 repo:https://github.com/AliyunContainerService/alibaba-cloud-metrics-adapter 1. 安装 AHAS Sen
- 下一篇
php数组去重的方法
本文实例讲述了PHP数组去重的更快实现方式。分享给大家供大家参考,具体如下: 使用PHP的array_unique()函数允许你传递一个数组,然后移除重复的值,返回一个拥有唯一值的数组。这个函数大多数情况下都能工作得很好。但是,如果你尝试在一个大的数组里使用array_unique()函数,它会运行地慢一些。 有一个比较好而且更快的函数array_flip()来替代使用array_unique()函数来创建唯一的数组。这个魔法般的函数会交换数组里面每一个元素的键和值,因为键值必须唯一,因此,你会得到跟array_unique()函数一样的结果。 运行结果: 因为我们已经移除了一些元素,因此数组看起来不是正常的序列。比如我们可能会得到:array(0=>'A',2=>'B',5=>'C');。在某些情况下,这不是一个问题,但是如果你需要数组的键值保持数字的序列,你可以使用一到两种方法解决键值乱序的问题。 使用array_merge修复数组的keys 添加array_flip之后的函数,将会对数组的键值排序并且让它们恢复到正常的序列,如:0,1,2,3…运行结果同上 ...
相关文章
文章评论
共有0条评论来说两句吧...