单例模式
阅读前,建议先了解单例模式,请点击这里。
介绍
作为对象的创建模式,多例模式中的多例类可以有多个实例,而且多例类必须自己创建、管理自己的实例,并向外界提供自己的实例。
多例模式的特点
所谓的多例模式(Multiton Pattern),实际上就是单例模式的自然推广。作为对象的创建模式,多例模式或多例类有以下特点:
- 多例类可有多个实例。
- 多例类必须自己创建、管理自己的实例,并向外界提供自己的实例。
有上限多例模式
一个实例数目有上限的多例类已经把实例的上限当做逻辑的 一部分,并建造到了多例类的内部,这种多例模式叫做有上限多例模式。
比如每一麻将牌局都需要两个骰子,因此骰子就应当是双态类,这里以该系统为例编写伪代码如下:
public class Die {
private static final Die die1 = new Die();
private static final Die die2 = new Die();
private Die() {
}
public static Die getInstance(int whichOne) {
if (whichOne == 1) {
return die1;
} else {
return die2;
}
}
/**
* 模拟投骰子
*
* @return 一个在1~6之间的随机数
*/
public synchronized int dice() {
Date d = new Date();
Random r = new Random(d.getTime());
int value = r.nextInt();
value = Math.abs(value);
value = value % 6;
value += 1;
return value;
}
}
public class DieClient {
public static void main(String[] args) {
Die die1 = Die.getInstance(1);
Die die2 = Die.getInstance(2);
die1.dice();
die2.dice();
}
}
无上限多例模式
多例类的实例数目并不需要有上限,实例数目没有上线的多例模式就叫做无上限多例模式。
由于没有上限的多例类对实例的数目是没有限制的,因此,虽然这种多例模式是单例模式的推广,但是这种多例类并不一定能回到单例类。
由于事先不知道要创建多少个实例,因此,必然使用聚集管理所有的实例。下面以伪代码实现多语言资源管理:
public class LingualResource {
private static final Map<String, LingualResource> bundles = new HashMap<>();
// 私有构造函数
private LingualResource() {
}
public static void registerService(@NotNull String lang, @NotNull LingualResource instance) {
if (!bundles.containsKey(lang)) {
bundles.put(lang, instance);
}
}
public static Object getService(String lang) {
return bundles.get(lang);
}
}
备注:注意“无上限多例模式”和单例模式中的“容器式单例类”区别。在“容器式单例类”中,一个单例对象同时也是一个聚集对象,这个聚集中所保存的是其他对象的引用。在“无上限多例模式”中,多例对象使用一个聚集对象登记和保存自身的实例。由于这两种设计模式的相似之处,在很多情况下它们可以互换使用。
有状态的和没有状态的多例类
如同单例类可以分成有状态的和没有状态的两种一样,多例类也可以分成有状态的和没有状态的两种。
具体可看这篇文章,请点击这里