详解java设计模式(七)之享元模式(结构型)

引言:

享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。我们在日常开发中经常遇到线程池的概念。

所谓池就是一些对象集合,为了避免对象无限被创建,并且待创建的对象都是相似的。享元模式可以实现对象的细粒度的控制。

一.享元模式:

FlyWeightFactory负责创建和管理享元单元,当一个客户端请求时,工厂需要检查当前对象池中是否有符合条件的对象,如果有,就返回已经存在的对象,如果没有,则创建一个新对象,FlyWeight是超类。


二.理解享元模式

我们以简单的map集合来作为对象池,享元模式基本逻辑如下所示:

1)一个key标识一个对象,

2)从对象池中查找key,如果找到则返回,否则执行3)。

3)创建新对象,并放入对象池中。

注:最核心的就是一个对象的内部状态可以通过外部状态来标识。就是通过特殊的辨识来查找对象,他们之间是对应关系。

private Map<String, Object> map = new HashMap<String, Object>
public Object get(String key) {
    if(map.containsKey(key)) {
        return map.get(key);
    }
    Object obj = new Object();
    map.put(key, obj);
    return obj;
}

三.开发案例

一提到共享池,我们很容易联想到Java里面的JDBC连接池,想想每个连接的特点,我们不难总结出:适用于作共享的一些个对象,他们有一些共有的属性,就拿数据库连接池来说,url、driverClassName、username、password及dbname,这些属性对于每个连接来说都是一样的,所以就适合用享元模式来处理,建一个工厂类,将上述类似属性作为内部数据,其它的作为外部数据,在方法调用时,当做参数传进来,这样就节省了空间,减少了实例的数量。

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Vector;
import cn.search.Util.XMLUtils;
/**
 * 该线程池是一个单例对象
 * @author cristo
 *
 */
public class ConnectionManager {
public static  Vector<Connection> pool=null;
public int initConnectionSize=5;
//已经创建的个数
private static int hasCreatedConnection=0;
//还在线程池中连接
private static int ConnectionInPool=0;
//实例化
private static  ConnectionManager manager=new ConnectionManager();
/**
 * 得到管理器
 * @return
 */
public static ConnectionManager getManager(){
	return manager;
}
private ConnectionManager(){
	try {
		init();
	} catch (Exception e) {
		throw new RuntimeException("mysql数据库初始化出错...");
	}
}
/**
 * 初始化连接池
 * @throws Exception
 */
public void init() throws Exception{
	pool = new Vector<Connection>(initConnectionSize);
	hasCreatedConnection=initConnectionSize;
	ConnectionInPool=initConnectionSize;
	for(int i=0;i<initConnectionSize;i++){
		Connection con=createConnection();
		pool.add(con);
	}
}
/**
 * 从线程池中取连接
 * @return
 * @throws Exception
 */
public  synchronized Connection getConnection() throws Exception{
	Connection con=null;
	if(ConnectionInPool>0){
	    con=pool.remove(0);
		ConnectionInPool--;
		return con;
	}
	else{
		 con=createConnection();
	}
	return con;
	}
/**
 * 返回连接
 * @param con
 */
public  synchronized void release(Connection con){
	if(con==null)
		return;
	pool.add(con);
	ConnectionInPool++;
}
/**
 * 创建连接,从配置文件中读取配置信息
 * @return
 * @throws Exception 
 */
public  Connection createConnection() throws Exception{
	Connection con=null;
	XMLUtils.parseArgs();
	String driver = XMLUtils.getAsString("driver");
	String url = XMLUtils.getAsString("url");
	String user = XMLUtils.getAsString("user");
	String pW =XMLUtils.getAsString("password");
	Class.forName(driver).newInstance();
	con = DriverManager.getConnection(url,user,pW);
	return con;
}
public static void main(String[]args){
	Thread t=new Thread(){
		ConnectionManager manager=ConnectionManager.getManager();
		public void run() {
			Connection con=null;
			try {
				con = manager.getConnection();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(con);
			manager.release(con);
		};
	};
//访问 
t.start();
}
}

四.总结

在实际开发中涉及到数据库这些共用资源时,一般都需要考虑建立一个资源池,以便避免程序无限创建对象,导致系统性能下降,内存损耗过大。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值