Flyweight模式也叫享元模式,是构造型模式之一,它通过与其他类似对象共享数据来减小内存占用。它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件。通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。 

  享元模式的角色和职责

    1、抽象享元角色:为具体享元角色规定了必须实现的方法,而外蕴状态就是以参数的形式通过此方法传入。在Java中可以由抽象类、接口来担当

    2、具体享元角色:实现抽象角色规定的方法。如果存在内蕴状态,就负责为内蕴状态提供存储空间。

    3、享元工厂角色:负责创建和管理享元角色。要想达到共享的目的,这个角色的实现是关键。

    4、客户端角色   :维护对所有享元对象的引用,而且还需要存储对应的外蕴状态。

  两个状态

    1、内蕴状态存储在享元内部,不会随环境的改变而有所不同,是可以共享的
    2、外蕴状态是不可以共享的,它随环境的改变而改变的,因此外蕴状态是由客户端来保持(因为环境的变化是由客户端引起的)。

  下面举个小例子

  首先,创建一个抽象享元角色

 public interface Flyweight {
public void display();
}

  接着,创建具体享元角色

 public class MyFlyweight implements Flyweight{
private String str; public MyFlyweight(String str){
this.str = str;
} public void display(){
System.out.println(str);
}
}  

  如果,不使用享元模式的话,不创建享元工厂,直接,创建客户端,代码如下:

 public class MainClass {
public static void main(String[] args) {
Flyweight myFlyweight1 = new MyFlyweight("a");
Flyweight myFlyweight2 = new MyFlyweight("b");
Flyweight myFlyweight3 = new MyFlyweight("a");
Flyweight myFlyweight4 = new MyFlyweight("d"); myFlyweight1.display();
myFlyweight2.display();
myFlyweight3.display();
myFlyweight4.display(); System.out.println(myFlyweight1 == myFlyweight3);
}
}

  这样子,运行结果为:

  这样子,可以看到,第一个与第三个明明都是a,但却不是同一个对象,说明虽然对象内部一模一样,但却创建了两个对象,这样就浪费了资源。

  如果用到享元模式,继续创建享元工厂

 public class MyFlyweightFactory {
private Map<String,MyFlyweight> pool; public MyFlyweightFactory(){
pool = new HashMap<String,MyFlyweight>();
} public Flyweight getMyFlyweight(String str){
MyFlyweight myFlyweight = pool.get(str); //若池中没有则创建一个新的并放入池中,若池中已存在,则返回池中的
if(myFlyweight == null){
myFlyweight = new MyFlyweight(str);
pool.put(str, myFlyweight);
} return myFlyweight;
}
}

  这样,修改客户端

 public class MainClass {
public static void main(String[] args) {
MyFlyweightFactory myFlyweightFactory = new MyFlyweightFactory();
Flyweight myFlyweight1 = myFlyweightFactory.getMyFlyweight("a");
Flyweight myFlyweight2 = myFlyweightFactory.getMyFlyweight("b");
Flyweight myFlyweight3 = myFlyweightFactory.getMyFlyweight("a");
Flyweight myFlyweight4 = myFlyweightFactory.getMyFlyweight("d"); myFlyweight1.display();
myFlyweight2.display();
myFlyweight3.display();
myFlyweight4.display(); System.out.println(myFlyweight1 == myFlyweight3);
}
}

  此时,结果就变为了

  可以看到,第一个与第三个变为了同一个对象,一模一样的对象只创建一次,节约了资源,这样,享元模式的作用就达到了。

  使用场景

  如果一个应用程序使用了大量的对象,而这些对象造成了很大的存储开销的时候就可以考虑是否可以使用享元模式。
例如,如果发现某个对象的生成了大量细粒度的实例,并且这些实例除了几个参数外基本是相同的,如果把那些共享参数移到类外面,在方法调用时将他们传递进来,就可以通过共享大幅度单个实例的数目。
  

java设计模式-----10、享元模式的更多相关文章

  1. Java设计模式之七 ----- 享元模式和代理模式

    前言 在上一篇中我们学习了结构型模式的组合模式和过滤器模式.本篇则来学习下结构型模式最后的两个模式, 享元模式和代理模式. 享元模式 简介 享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能 ...

  2. 11.java设计模式之享元模式

    基本需求: 小型的外包项目,给客户A做一个产品展示网站,客户A的朋友感觉效果不错,也希望做这样的产品展示网站,但是要求都有些不同 每个客户要求发布的方式不一样,A要求以新闻的方式发布,B要求以博客的方 ...

  3. JAVA设计模式之享元模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述享元(Flyweight)模式的: Flyweight在拳击比赛中指最轻量级,即“蝇量级”或“雨量级”,这里选择使用“享元模式”的意译,是 ...

  4. 由奶茶店突发奇想开始了Java设计模式:享元模式

    目录 定义 意图 主要解决问题 何时使用 优缺点 结构 奶茶摊位的例子 奶茶店的例子 在什么情况下使用享元模式 定义 享元模式是对象的结构模式,享元模式以共享的方式高效的支持大量的细粒度对象,主要用于 ...

  5. python设计模式之享元模式

    python设计模式之享元模式 由于对象创建的开销,面向对象的系统可能会面临性能问题.性能问题通常在资源受限的嵌入式系统中出现,比如智能手机和平板电脑.大型复杂系统中也可能会出现同样的问题,因为要在其 ...

  6. 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern)

    原文:乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) 作者:weba ...

  7. Java进阶篇设计模式之七 ----- 享元模式和代理模式

    前言 在上一篇中我们学习了结构型模式的组合模式和过滤器模式.本篇则来学习下结构型模式最后的两个模式, 享元模式和代理模式. 享元模式 简介 享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能 ...

  8. Java设计模式15:常用设计模式之享元模式(结构型模式)

    1. Java之享元模式(Flyweight Pattern) (1)概述:       享元模式是对象池的一种实现,英文名为"Flyweight",代表轻量级的意思.享元模式用来 ...

  9. 设计模式(C#)——10享元模式

    推荐阅读:  我的CSDN  我的博客园  QQ群:704621321 前言       在软件开发中,当我们需要对某些对象重复创建,且最终只需要得到单一结果.如果使用一般思维,那我们将浪费很多内存空 ...

  10. 【GOF23设计模式】享元模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_享元模式.享元池.内部状态.外部状态.线程池.连接池 package com.test.flyweight; /** * ...

随机推荐

  1. pandas 对dataframe一列中某些值进行处理

    https://github.com/Bifzivkar/Boutique-Travel-Services-Predict/blob/master/feature/5_extract_feature. ...

  2. BZOJ 1001--[BeiJing2006]狼抓兔子(最短路&对偶图)

    1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 29035  Solved: 7604 Descript ...

  3. elasticsearch geo_point 地理位置过滤 按经度排序

    elasticsearch 支持强大的经纬度坐标过滤. 1.首先要建立坐标类型的字段'type' ='geo_point' es存储的值是这样的: "poi": [        ...

  4. powerDesiner设计数据库的一些用法

    数据库的设计主要有以下几个步骤: 1:需求分析:根据业务需求分析出满足客户的需求,从而建立相应的数据库 2:概念设计:通过数据抽象,设计系统概念模型,一般为E-R模型:(entity-relation ...

  5. iOS开发--应用国际化,应用内切换语言

    1.前言 自己负责的项目需要做国际化,并且要求应用内部切换语言.这个是可以做到的,也并不难,可以直接戳Github看一下 https://github.com/leo90821/Localiztion ...

  6. iOS-WKWebview 带有进度条加载的ViewController【KVO监听Webview加载进度】

    前言 为什么要说 WKWebview,在之前做电子书笔记时已经提过 WKWebview 在iOS8之后已完全替代 Webview,原因就不多说了,主要还是内存过大: 封装 封装一个基于 UIViewC ...

  7. 贪吃蛇小游戏-----C语言实现

    1.分析 众所周知,贪吃蛇游戏是一款经典的益智游戏,有PC和手机等多平台版本,既简单又耐玩.该游戏通过控制蛇头方向吃食物,从而使得蛇变得越来越长,蛇不能撞墙,也不能装到自己,否则游戏结束.玩过贪吃蛇的 ...

  8. leetcode-165-比较版本号

    题目描述: 比较两个版本号 version1 和 version2.如果 version1 > version2 返回 1,如果 version1 < version2 返回 -1, 除此 ...

  9. 【xsy1147】 异或(xor) 可持久化trie

    我的脑回路可能比较奇怪. 我们对这些询问离线,将所得序列${a}$的后缀和建$n$棵可持久化$trie$. 对于一组询问$(l,r,x)$,我们在主席树上询问第$l$棵树$-$第r$+1$棵树中与$s ...

  10. (转)AWK函数

    http://wiki.jikexueyuan.com/project/awk/built-in-functions.html-------内置函数 http://wiki.jikexueyuan.c ...