单例模式可以说是23中设计模式中最简单的模式之一了。
单例模式,顾名思义,只有一个实例,因此这种模式只有在真正的需求“单一实例”的时候使用。它提供一种方法来确保某一特定类型有且只有一个实例。而且自行实例化,并向外部提供这个单一实例。
在它核心结构中,只包含一个被被称为单例类的特殊类(static:确保只有一个对象),并向外部提供一个全局的存取点(static method)。
单例模式的要点有三个:
一是某个类只能有一个实例,
二是它必须自行创建这个实例,
三是它必须自行向整个系统提供这个实例。
从具体实现角度来说,就是以下三点:
一是单例模式的类只提供私有的构造函数,
// private constructor method, others can not use: new Singleton();
private Singleton() {
}
二是类定义中含有一个该类的静态私有对象,
private static Singleton s = new Singleton();
or
private static Singleton s = null;
三是该类提供了一个静态的共有的函数用于创建或获取它本身的静态私有对象。
// static method
public static Singleton getReference() {
return s;
}
这种思想模式同样适用于创建固定数量的对象。但是这种情况下,你得面临如何共享对象池里的对象这种问题。数据库连接池就是以这种方式实现对数据库连接的管理。
下面是一个简单的连接池模拟:
一是创建一个List,用来存储一定数量的对象,设置添加:add(),取出:get(),释放:release()。
public class PoolManager {
private final List<PoolItem> items = new ArrayList<PoolItem>();
public void addItem(final Object item) {
items.add(new PoolItem(item));
}
public Object getItem() throws EmptyPoolException {
for (int i = 0; i < items.size(); i++) {
final PoolItem pItem = items.get(i);
if (pItem.isUse == false) {
pItem.isUse = true;
return pItem.item;
}
}
return null;
// throw new EmptyPoolException();
}
public void releaseItem(final Object item) {
for (int i = 0; i < items.size(); i++) {
final PoolItem pItem = items.get(i);
if (item == pItem.item) {
pItem.isUse = false;
return;
}
}
throw new RuntimeException(item + "not found.");
}
// simple pool item design
private static class PoolItem {
boolean isUse = false;
Object item;
PoolItem(final Object item) {
this.item = item;
}
}
// simple empty pool exception simulation
static class EmptyPoolException extends Exception {
private static final long serialVersionUID = 1L;
}
}
二是将对象设置成Singleton。
public class ConnectionPool {
private static PoolManager pool = new PoolManager();
private ConnectionPool() {
}
public static void addConnections(final int number) {
for (int i = 0; i < number; i++) {
pool.addItem(new ConnectionImpl());
}
}
public static Connection getConnection() throws EmptyPoolException {
return (Connection) pool.getItem();
}
public static void releaseConnection(final Connection c) {
pool.releaseItem(c);
}
}
三是初始化。
static {
ConnectionPool.addConnections(4);
}
四就是我们熟悉的获取连接了。
public void test() {
Connection c = null;
try {
c = ConnectionPool.getConnection();
c.setItem(new Object());
c.getItem();
ConnectionPool.releaseConnection(c);
} catch (final EmptyPoolException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
本文为学习过程中收集资料总结而成,如有雷同,纯属巧合。