Flyweight 享元模式 MD
| 我的GitHub | 我的博客 | 我的微信 | 我的邮箱 |
|---|---|---|---|
| baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
享元模式
简介
在JAVA语言中,String类型就是使用了享元模式,JAVA中的字符串常量都是存在常量池中的,JAVA会确保一个字符串常量在常量池中只有一个拷贝,避免了在创建N多相同对象时所产生的不必要的大量的资源消耗。
String string1 = "abc";
String string2 = "abc";
String string3 = new String("abc");
String string4 = new String("abc");
System.out.println(string1 == string2);//true
System.out.println(string3 == string4 || string3 == string1 || string4 == string1);//false
享元模式是对象的结构模式,享元模式以共享的方式高效地支持大量的细粒度对象。
Flyweight在拳击比赛中指最轻量级拳击选手,即“蝇量级”,这里选择使用“享元模式”的意译,是因为这样更能反映模式的用意。
享元模式使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件。通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。
享元对象能做到共享的关键是区分内蕴状态Internal State和外蕴状态External State。
- 一个内蕴状态是存储在享元对象内部的,并且是不会随环境的改变而有所不同。因此,一个享元可以具有内蕴状态并可以共享。
- 一个外蕴状态是随环境的改变而改变的、不可以共享的。享元对象的外蕴状态必须由客户端保存,并在享元对象被创建之后,在需要使用的时候再传入到享元对象内部。
- 外蕴状态不可以影响享元对象的内蕴状态,它们是相互独立的。
享元模式所涉及到的角色如下:
- 抽象享元(Flyweight)角色 :给出一个抽象接口,以规定出所有具体享元角色需要实现的方法。
- 具体享元(ConcreteFlyweight)角色:实现抽象享元角色所规定出的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。
- 享元工厂(FlyweightFactory)角色 :负责创建和管理享元角色。
本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象调用一个享元对象的时候,享元工厂角色会检查系统中是否已经有一个符合要求的享元对象,如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个合适的享元对象。
享元模式的优点在于它大幅度地降低内存中对象的数量,但是,它做到这一点所付出的代价也是很高的:
- 享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化
- 享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长
作用:共享对象,节省内存
优点:享元模式可以降低内存中的对象数量,提高性能
缺点:需要将一些状态外部化,程序逻辑将变得复杂,且在读取外部状态时耗时增加
案例
抽象享元类
public interface IFlyweight {
action(int arg);//参数是外蕴状态,通过这个接口,享元类可以接受并作用于外部状态
}
具体享元类
public class ConcreteFlyweight implements IFlyweight {
private String intrinsicState = null;//有一个内蕴状态,内蕴状态在对象创建之后,就不能再改变了
public ConcreteFlyweight(String intrinsicState) {
this.intrinsicState = intrinsicState; //一般在构造享元对象时通过参数确定内蕴状态
}
@Override
public void action(int arg) { //外蕴状态作为参数传入方法中,可以改变方法的行为,但并不改变对象的内蕴状态
System.out.println("参数值: " + arg + " intrinsicState = " + this.intrinsicState);
}
}
享元工厂类
客户端不可以直接构造享元类对象,只能由享元工厂创建并管理,在一个项目中只会存在一个享元工厂,因此用单例来获取,而享元对象则通过工厂获取,有则取用,无则创建
public class FlyweightFactory {
private Map<String, IFlyweight> flyweights = new HashMap<>();//存储已创建的对象
public IFlyweight getFlyweight(String arg) {
IFlyweight flyweight = flyweights.get(arg); //先从系统中取,如果存在直接使用,如果不存在则创建并保存起来
if (flyweight == null) {
flyweight = new ConcreteFlyweight(arg);
flyweights.put(arg, flyweight);
}
return flyweight;
}
//以下是标准的单例模式写法
private FlyweightFactory() {
}
public static FlyweightFactory getInstance() {
return SingleHolder.INSTANCE;
}
private static class SingleHolder {
private static final FlyweightFactory INSTANCE = new FlyweightFactory();
}
}
2016-03-17
Flyweight 享元模式 MD的更多相关文章
- C++设计模式-Flyweight享元模式
Flyweight享元模式 作用:运用共享技术有效地支持大量细粒度的对象. 内部状态intrinsic和外部状态extrinsic: 1)Flyweight模式中,最重要的是将对象分解成intrins ...
- Flyweight享元模式(结构型模式)
1.面向对象的缺点 虽然OOP能很好的解决系统抽象的问题,并且在大多数的情况下,也不会损失系统的性能.但是在某些特殊的业务下,由于对象的数量太多,采用面向对象会给系统带来难以承受的内存开销.示例代码如 ...
- 设计模式之flyweight享元模式
运用共享技术支持大量细粒度对象的使用 Flyweight模式(享元) Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模 ...
- 设计模式11: Flyweight 享元模式(结构型模式)
Flyweight 享元模式(结构型模式) 面向对象的代价 面向对象很好的解决了系统抽象性的问题,同时在大多数情况下也不会损及系统的性能.但是,在某些特殊应用中,由于对象的数量太大,采用面向对象会给系 ...
- 20、FlyWeight 享元模式
池化的思想 1.Flyweight享元模式 运用共享技术有效地支持大量细粒度对象的复用.系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用.由于享元模式要求能够共享的对象必 ...
- Flyweight(享元模式)
import java.util.Hashtable; /** * 享元模式 * @author TMAC-J * 享元模式一般和工厂模式一起使用,但此处为了更好说明,只用享元模式 * 定义:享元模式 ...
- 设计模式(十二): Flyweight享元模式 -- 结构型模式
说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释放.我们只是为了学习而简单做了介绍. 1. 概述 面 ...
- 二十、Flyweight 享元模式
原理: 代码清单: BigChar public class BigChar { //字符名称 private char charname; //大型字符 # . \n 组成 private Stri ...
- 设计模式(11)--Flyweight(享元模式)--结构型
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.模式定义: 享元模式是对象的结构模式.享元模式以共享的方式高效地支持大量的细粒度对象. 2.模式特点: 享元模 ...
随机推荐
- [USACO3.2]Sweet Butter
题目大意: 给定一张$k$个结点,$m$条边的无向图,其中有$n$个点被标记,在这$k$个点中找出一个点使得这个点到那$n$个点的最短距离之和最小,求出这个距离和. 思路: 对于每个标记结点跑最短路, ...
- OpenJ_POJ C16D Extracurricular Sports 打表找规律
Extracurricular Sports 题目连接: http://acm.hust.edu.cn/vjudge/contest/122701#problem/D Description As w ...
- Android内存机制分析——堆和栈
昨天用Gallery做了一个图片浏览选择开机画面的功能,当我加载的图片多了就出现OOM问题.以前也出现过这个问题,那时候并没有深究.这次打算好好分析一下Android的内存机制. 因为我以前是做VC+ ...
- dell T420热插拔安装过程
http://v.youku.com/v_show/id_XNTUzMjk4NTQw.html
- 3I工作室的成员在2013年(第6届)中国大学生计算机设计大赛总决赛中荣获全国二等奖
在暑假举行的2013年(第6届)中国大学生计算机设计大赛中,我院的参赛作品<毕业生论文选导系统>(作者:祝丽艳/许明涛:指导老师:元昌安/彭昱忠)入围总决赛,并荣获全国二等奖. 2013年 ...
- 大不列颠百科全书Encyclopaedia Britannica Ultimate 2014光盘镜像
大不列颠百科全书又名大英百科全书,是目前最古老的百科全书之一.大英百科全书每10余年出一个版本,如今已经推出到Encyclopaedia Britannica Ultimate 2014.此次推荐的是 ...
- .net项目中使用Quartz
(1)在web.config中进行相关配置 <configSections> <section name="quartz" type="System.C ...
- springboot线程池的使用和扩展(转)
springboot线程池的使用和扩展 我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行, ...
- Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(4) DateFormat
本章主要介绍DateFormat. DateFormat 介绍 DateFormat 的作用是 格式化并解析“日期/时间”.实际上,它是Date的格式化工具,它能帮助我们格式化Date,进而将Date ...
- Android 实现页面跳转并传递参数教程
首先我们来看一下实现的功能: 第二,我们看一下实现这个功能,总共会接触到哪些文件和代码. 1.实现本功能总共涉及如下6个文件 2.实现本功能,总共涉及如下6个文件中的如下代码: (1) 效果: ...