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. bonjour browser 下载

    在Mac 上叫 Bonjour Browser http://www.macupdate.com/app/mac/13388/bonjour-browser/download IOS 上的 app 叫 ...

  2. 找到SVN版本机上项目的地址

    在你的项目文件上右击:点击Copy URL to Clipboard(复制URL到剪切板)

  3. java.util包详解

    介绍Java的实用工具类库java.util包.在这个包中,Java提供了一些实用的方法和数据结构.本章介绍Java的实用工具类库java.util包.在这个包中,Java提供了一些实用的方法和数据结 ...

  4. 00-python概述。

    人生苦短,我用Python. -发展历史: - 1989年,由Guido van Rossum开始开发, - 1991年,发布第一个公开发行版,第一个Python编译器(同时也是解释器)诞生. - 2 ...

  5. Java多线程实现异步调用

    在Java平台,实现异步调用的角色有如下三个角色:调用者. 提货单 .真实数据,一个调用者在调用耗时操作,不能立即返回数据时,先返回一个提货单 .然后在过一断时间后凭提货单来获取真正的数据.去蛋糕店买 ...

  6. 深度学习笔记(六)VGG14

    Very Deep Convolutional Networks for Large-Scale Image Recognition 1. 主要贡献 本文探究了参数总数基本不变的情况下,CNN随着层数 ...

  7. Python小白学习之路(十四)—【作用域】【匿名函数】【编程方法论】【高阶函数】

    吧啦吧啦内心戏 在没有具体学作用域之前,我在之前的学习笔记中就有提到 我开始以为是自己自创的词儿 没想到这个词早已经存在(手动捂脸) 真是个无知的小火锅(不知者无罪) 我发现自己最擅长做的事情,就是给 ...

  8. 小div在大div里面水平垂直都居中的实现方法

    关于如何设置小盒子在大盒子里面水平垂直方向同时居中的实现方法有很多种,下面仅列举了常用的几种. 首先看一下要实现的效果图及对应的html代码: <div class="parent&q ...

  9. linux,修改文件夹权限

    chmod -R 777 dist/ chown windseek:staff dist/   改变dist的权限到staff组里的windseek用户下   alias ll=`ls -al`   ...

  10. c++类定义和类实现

    预备知识: c++中我们cpp文件和.h文件的区别是,cpp文件是需要编译的文件,成为一个独立的编译单元,而h文件从来是不需要编译,只是用于预处理. 通常我们在cpp文件中,完成函数的实现,然后在h中 ...