缓存应用:单例模式在缓存机制中的应用 

    单例模式:顾名思义,一个系统中中定义的某类只有一个实例。
    缓存应用:将要用到的资源提前从数据库或其他地方下载到内存,提高系统反应速度,增强用户体验满意度。
    本例子来自于一个真实的项目,作者巧妙地将单例模式应用于缓存机制中。阅读本文,对单例模式,缓存机制都可以有进一步的认识和把握。

    背景:
    JavaME 中绘制本地图片太频繁,同一图片不同地方绘制,每次都要下载图片,每次都要新建对象。

    解决方案:
    缓存应用:加载程序时,将所有有可能画的本地图片全部下载到缓存,需要绘制的时候直接从缓存中读取.由于缓存器被设置为登记式缓存,即使以后有新图片加入本地资源,也无须更改原有代码,直接在新增功能程序里调用缓存即可。

    具体实现:采用单例的设计模式来实现缓存应用。原因:缓存控制器整个系统中只需要一个即可。

    源代码:
    ImageBean.java(封装下载的图片的 Javabean)

package com.xxx.bean;
/**
* 文件名:ImageBean.java
*
* 版本信息:
* 日期:2009-10-21
* Copyright xxx Corporation 2009
* 版权所有
*
*/
/**
*
* 项目名称:Test
* 类名称:ImageBean
* 类描述:封装下载的图片的 Javabean.
* 创建人:Defonds
* 创建时间:2009-10-21 上午11:30:45
* 修改人:Defonds
* 修改时间:2009-10-21 上午11:30:45
* 修改备注:
* @version
*
*/
public class ImageBean
{
//------------------------------------------------------
//fields.

/**
* 地图图片的横坐标.
*/
private int abscissa;

/**
* 地图图片的纵坐标.
*/
private int ordinate;

/**
* 要下载地图的 http url 链接地址.
*/
private String url;

/**
* 下载的图片的字节流.
*/
private byte[] byteOfImage;
//--------------------------------------------------------------------
//The getters and setters.

public int getAbscissa()
{
return abscissa;
}
public void setAbscissa(int abscissa)
{
this.abscissa = abscissa;
}
public int getOrdinate()
{
return ordinate;
}
public void setOrdinate(int ordinate)
{
this.ordinate = ordinate;
}
public String getUrl()
{
return url;
}
public void setUrl(String url)
{
this.url = url;
}
public byte[] getByteOfImage()
{
return byteOfImage;
}
public void setByteOfImage(byte[] byteOfImage)
{
this.byteOfImage = byteOfImage;
}

}


    ImageManager.java(单例类负责所有本地图片的管理工作 [缓存器的管理类])

/**
* 文件名:ImageManager.java
*
* 版本信息:
* 日期:2009-10-28
* Copyright xxx Corporation 2009
* 版权所有
*
*/
package com.xxx.util;
import java.io.IOException;
import java.util.Hashtable;
import javax.microedition.lcdui.Image;
/**
*
* 项目名称:Basic1.0
* 类名称:ImageManager
* 类描述:单例类负责所有本地图片的管理工作 [缓存器的管理类]
* 创建人:Defonds
* 创建时间:2009-10-28 上午11:32:43
* 修改人:Defonds
* 修改时间:2009-10-28 上午11:32:43
* 修改备注:
* @version
*
*/
public class ImageManager
{
/**
* 缓存器.专门用来存放程序中用到的图片.
*/
private static Hashtable imageCache = null;

/**
* 饿汉式单例模式,类加载器加载时就有了本类的一个实例,提高了系统效率.
*/
private static ImageManager instance = new ImageManager();
/**
* 私有的构造子,防止被任意调用,保证本类在整个项目中只能有一个实例.
*/
private ImageManager()
{
imageCache = new Hashtable();
}
/**
* 这里提供了一个供外部调用本 class 的静态方法,可以直接访问
*/
public static ImageManager getInstance()
{
return instance;
}
/**
* 登记式缓存器的应用.
* 如果图片是第一次访问本方法,产生一个实例并返回.同时将此实例加载到缓存器之中
* 如果图片是第2,3,,,n次访问本方法,直接返回该图片实例,大大提高了系统运行效率
*/
public Image getImage(String name)
{
Image image = null;
try
{
System.out.println("111111111111111");
if (null == imageCache.get(name))
{
System.out.println("222222222222222");
image = Image.createImage("/" + name + ".png");
System.out.println("33333333333333333333");
imageCache.put(name, image);
}else
{
image = (Image)imageCache.get(name);
}
}catch (IOException ioe)
{
ioe.printStackTrace();
}

return image;
}

/**
* 批量将一个数组中所有的图片放入缓存器[一般是在 MIDlet 中对缓存器初始化时使用
*/
public void loadImagesCache(String[] names)
{
for (int i = 0; i < names.length; i++)
{
try
{
if (names[i] != null)
{
imageCache.put(names[i], Image.createImage("/" + names[i] + ".png"));
}
}catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
}


    客户端使用缓存示例:

ImageManager imageManager = ImageManager.getInstance();
Image image = imageManager.getImage("logo");