Java设计模式之享元模式实例详解
作者:炸斯特 发布时间:2021-12-19 17:54:00
本文实例讲述了Java设计模式之享元模式。分享给大家供大家参考,具体如下:
解释一下概念:也就是说在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象。比如说一个文本系统,每个字母定一个对象,那么大小写字母一共就是52个,那么就要定义52个对象。如果有一个1M的文本,那么字母是何其的多,如果每个字母都定义一个对象那么内存早就爆了。那么如果要是每个字母都共享一个对象,那么就大大节约了资源。
在Flyweight模式中,由于要产生各种各样的对象,所以在Flyweight(享元)模式中常出现Factory模式。Flyweight的内部状态是用来共享的,Flyweight factory负责维护一个对象存储池(Flyweight Pool)来存放内部状态的对象。Flyweight模式是一个提高程序效率和性能的模式,会大大加快程序的运行速度.应用场合很多,下面举个例子:
先定义一个抽象的Flyweight类:
package Flyweight;
public abstract class Flyweight{
public abstract void operation();
}
实现一个具体类:
package Flyweight;
public class ConcreteFlyweight extends Flyweight{
private String string;
public ConcreteFlyweight(String str){
string = str;
}
public void operation()
{
System.out.println("Concrete---Flyweight : " + string);
}
}
实现一个工厂方法类:
package Flyweight;
import java.util.Hashtable;
public class FlyweightFactory{
private Hashtable flyweights = new Hashtable();//----------------------------1
public FlyweightFactory(){}
public Flyweight getFlyWeight(Object obj){
Flyweight flyweight = (Flyweight) flyweights.get(obj);//----------------2
if(flyweight == null){//---------------------------------------------------3
//产生新的ConcreteFlyweight
flyweight = new ConcreteFlyweight((String)obj);
flyweights.put(obj, flyweight);//--------------------------------------5
}
return flyweight;//---------------------------------------------------------6
}
public int getFlyweightSize(){
return flyweights.size();
}
}
这个工厂方法类非常关键,这里详细解释一下:
在1处定义了一个Hashtable用来存储各个对象;在2处选出要实例化的对象,在6处将该对象返回,如果在Hashtable中没有要选择的对象,此时变量flyweight为null,产生一个新的flyweight存储在Hashtable中,并将该对象返回。
最后看看Flyweight的调用:
package Flyweight;
import java.util.Hashtable;
public class FlyweightPattern{
FlyweightFactory factory = new FlyweightFactory();
Flyweight fly1;
Flyweight fly2;
Flyweight fly3;
Flyweight fly4;
Flyweight fly5;
Flyweight fly6;
/** *//** Creates a new instance of FlyweightPattern */
public FlyweightPattern(){
fly1 = factory.getFlyWeight("Google");
fly2 = factory.getFlyWeight("Qutr");
fly3 = factory.getFlyWeight("Google");
fly4 = factory.getFlyWeight("Google");
fly5 = factory.getFlyWeight("Google");
fly6 = factory.getFlyWeight("Google");
}
public void showFlyweight(){
fly1.operation();
fly2.operation();
fly3.operation();
fly4.operation();
fly5.operation();
fly6.operation();
int objSize = factory.getFlyweightSize();
System.out.println("objSize = " + objSize);
}
public static void main(String[] args){
System.out.println("The FlyWeight Pattern!");
FlyweightPattern fp = new FlyweightPattern();
fp.showFlyweight();
}
}
下面是运行结果:
Concrete---Flyweight : Google
Concrete---Flyweight : Qutr
Concrete---Flyweight : Google
Concrete---Flyweight : Google
Concrete---Flyweight : Google
Concrete---Flyweight : Google
objSize = 2
我们定义了6个对象,其中有5个是相同的,按照Flyweight模式的定义“Google”应该共享一个对象,在实际的对象数中我们可以看出实际的对象却是只有2个。
总结:
Flyweight(享元)模式是如此的重要,因为它能帮你在一个复杂的系统中大量的节省内存空间。在JAVA语言中,String类型就是使用了享元模式。String对象是final类型,对象一旦创建就不可改变。在JAVA中字符串常量都是存在常量池中的,JAVA会确保一个字符串常量在常量池中只有一个拷贝。String a="abc",其中"abc"就是一个字符串常量。
熟悉java的应该知道下面这个例子:
String a = "hello";
String b = "hello";
if(a == b)
System.out.println("OK");
else
System.out.println("Error");
输出结果是:OK。可以看出if条件比较的是两a和b的地址,也可以说是内存空间
核心总结,可以共享的对象,也就是说返回的同一类型的对象其实是同一实例,当客户端要求生成一个对象时,工厂会检测是否存在此对象的实例,如果存在那么直接返回此对象实例,如果不存在就创建一个并保存起来,这点有些单例模式的意思。通常工厂类会有一个集合类型的成员变量来用以保存对象,如hashtable,vector等。在java中,数据库连接池,线程池等即是用享元模式的应用。
更多java相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》
希望本文所述对大家java程序设计有所帮助。
来源:https://blog.csdn.net/jason0539/article/details/22908915
猜你喜欢
- 本文介绍IntelliJ IDEA中Project 窗口的一些设置技巧,参考IntelliJ IDEA 简体中文专题教程,英文好的同学可以查
- SpringMvc中普通类注入Service为null场景:使用Quartz定时器时,普通的java类需要注入spring的service类
- 1: .net framework 由两个部分组成:CLR 和 FCL。2:在CLR中,所有错误都是通过异常来报告的。3:智能感知功能主要是
- JAVA 中Spring的@Async用法总结引言: 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的;但是在处理与第三方
- JPanel是面板组件,非顶层容器,一个界面只有可以有一个JFrame窗体组件,但可以有多个Jpanel面板,而JPanel上也可以使用Fl
- 近日,开发者头条上分享了一篇“小米java第二轮面经”,有很多的java程序员表示非常有兴趣。下面就和各位分享小米java第二轮面经:0、谈
- 前言前阵子有同学反馈Flutter中的http请求无法通过fiddler抓包,作者喜欢使用Charles抓包工具,于是抽时间写了个小demo
- 为开发团队选择一款优秀的MVC框架是件难事儿,在众多可行的方案中决择需要很高的经验和水平。你的一个决定会影响团队未来的几年。要考虑方面太多:
- 参数和返回值得加密目的为了保证接口不被人拦截下来恶意请求,保证程序的稳定性,我们可以使用接口加密的方法来保证参数和返回值的保密性。具体实现方
- 在使用 springboot 或者 springcloud 开发的时候,通常为了保证系统的安全性,配置文件中的密码等铭感信息都会进行加密处理
- 前言一个说难不难,说简单竟看不出来是哪里问题的一个bug。是的 可能自己能力和经验尚浅无法识别,下面你们能否用火眼金睛一眼让bug原形毕露(
- 今天讲解一下Fragment的控制,主要是切换View和页面替换等操作。还有就是如何获取Fragment的管理对象,以及与Activity的
- 这篇文章主要介绍了SpringBoot跨域Access-Control-Allow-Origin实现解析,文中通过示例代码介绍的非常详细,对
- 先看Demo运行效果SharedPreferences详解SharedPreferences是Android平台上一个轻量级的存储类,用来保
- servlet、filter、listener、interceptor之间的区别和联系一、概念1.servlet:servlet是一种运行服
- 简介机器学习在全球范围内越来越受欢迎和使用。 它已经彻底改变了某些应用程序的构建方式,并且可能会继续成为我们日常生活中一个巨大的(并且正在增
- 一. 线性表中的顺序表线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见
- 骑缝章是用于往来业务合同,以确保合同真实、有效的印章加盖方法,是一种防范风险的重要方式。在Java程序中,可以通过使用工具来辅助加盖这种骑缝
- 方式1:1. 明确 Spark中Job 与 Streaming中 Job 的区别1.1 Spark Core一个 RDD DAG Graph
- 本文实例讲述了Java基于Runtime调用外部程序出现阻塞的解决方法, 是一个很实用的技巧。分享给大家供大家参考。具体分析如下:有时候在j