Java设计模式概述之结构型模式(享元模式)

五、享元模式(Flyweight)

享元模式简介

Flyweight本意是拳击中的绳量级,在这里是指代共享的元素。

享元模式指多个元素共享使用。把生活中的公共设施比作这里的元素,每个人都能享用元素,人人共享资源。享元模式最大的特点就是资源共享性。

Java中String类型利用了享元模式。代码如下:

String a = "abc";
String b = "abc";

System.out.println(a == b);

打印结果:true。

分析:”abc”本质上是字符串常量,存储在常量池中,常量池位于方法区(Method Area)区中,什么是常量池?

常量池指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。除了包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值(final)还包含一些以文本形式出现的符号引用,比如:

  • 类和接口的全限定名
  • 字段的名称和描述符
  • 方法和名称和描述符

Java虚拟机收到创建字符串常量”abc”的命令后,首先会检查方法区中的常量池是否含有”abc”字符串,检查完毕,没有,于是创建字符串常量”abc”,然后赋值给a引用变量,至此a就有了”abc”的引用。b引用变量创建时,Java虚拟机检查字符串常量是否有”abc”,有,直接将现成的”abc”赋值给b变量,b也有了”abc”的引用。由于”abc”在方法区中的内存地址是固定的,因此a、b引用的是同一个内存地址值,a == b,当然返回true。

这就是一个典型的享元模式架构。

享元模式结构

  • 元素仓库类(FlyweightWarehouse)
  • 元素类(Flyweight)

元素类是就是指一类元素,这类元素可以是任意类型的。

元素仓库类是用来存储若干个元素的,一般情况下以Hashtable双列集合封装,key为元素的标识,value为元素类实例。元素仓库类为了保证元素共享,其封装若干元素的集合类的成员变量必须用static修饰,变量初始化使用static代码块。元素仓库类最基本的功能就是供给共享的元素,这也是享元模式的精髓所在。

代码:

import java.util.HashMap;
import java.util.Map;

/**
 * @author Hanlin Wang
 */

public class FlyweightMode {
    public static void main(String[] args) {
        Flyweight ele = FlyweightWareHouse.getFlyweight(1);
        System.out.println(ele.getInfo());
    }
}

//元仓库类
class FlyweightWareHouse{
    //在类加载时就完成初始化
    private static Map<Integer, Flyweight> flyweights = new HashMap<Integer, Flyweight>();
    //flyweights初始化
    static{
        flyweights.put(1, new Flyweight("MySQL"));
        flyweights.put(2, new Flyweight("Oracle"));
        flyweights.put(3, new Flyweight("HBase"));
        flyweights.put(4, new Flyweight("MongoDB"));
    }
    //得到元素的方法
    public static Flyweight getFlyweight(int key){
        return flyweights.get(key);
    }
}


//元类
class Flyweight{
    //元素类的信息
    private String info;

    //通过构造方法初始化info
    public Flyweight(String info) {
        this.info = info;
    }

    //info成员变量的getter、setter
    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }
}

解析:Flyweight为元素类,info为属性,info属性通过构造方法初始化,并带有getter、setter方法。FlyweightWarehouse为元素仓库,flyweights属性为Map类型,其key为标识,value为Flyweight的实例对象,必须以static修饰。FlyweightWarehouse提供了一个方法getFlyweight(int key),用于获取共享的元素。

posted @ 2017-02-06 21:20  晚樨  阅读(178)  评论(0编辑  收藏  举报