大B:“你知不知道单体模式有哪些不同表现形式?”
小A:“我知道。不同表现形式:1、饿汉式单体类:类被加载的时候将自己初始化。更加安全些。2、懒汉式单体类:在第一次被引用的时候将自己初始化。提高了效率。3、多例类(多例模式):除了可以提供多个实例,其他和单体类没有区别。”
大B:“不错,我再详细说给你听吧!”
单体模式的不同表现形式之:多例类(多例模式)
所谓多例(Multiton Pattern)实际上就是单例模式的自然推广。作为对象的创建模式,多例模式或多例类有以下的特点:
1、多例类可以有多个实例
2、多例类必须自己创建,管理自己的实例,并向外界提供自己的实例。这种允许有限个或无限个实例,并向整个JVM提供自己实例的类叫做多例类,这种模式叫做多例模式。
(1)有上限多例模式。有上限的多例类已经把实例的上限当作逻辑的一部分,并建造到了多例类的内部,这种多例模式叫做有上限多例模式。
import java。util。Random;
import java。util。Date;
public class Die
{
private static Die die1=new Die();
private static Die die2=new Die();
/ *私有的构造函数保证外界无法直接将此类实例化
*
*/
private Die()
{
}
/ *工厂方法
*/
public static Die getInstance(int whichOne)
{
if(whichOne……1)
{
return die1;
}else{
return die2;
}
}
/ *投骰子,返回一个在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;//对6取模
value+=1;//由于value的范围是0~5,所以value+1成为1~6
return value;
}
}
/ *测试的客户端,投掷骰子
*/
public class DieClient
{
private static Die die1,die2;
public static void main(String[]args)
{
die1=Die。getInstance(1);
die2=Die。getInstance(2);
System。out。println(die1.dice());
System。out。println(die2.dice());
}
}
import java。util。Random;
import java。util。Date;
public class Die
{
private static Die die1=new Die();
private static Die die2=new Die();
/ *私有的构造函数保证外界无法直接将此类实例化
*
*/
private Die()
{
}
/ *工厂方法
*/
public static Die getInstance(int whichOne)
{
if(whichOne……1)
{
return die1;
}else{
return die2;
}
}
/ *投骰子,返回一个在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;//对6取模
value+=1;//由于value的范围是0~5,所以value+1成为1~6
return value;
}
}
/ *测试的客户端,投掷骰子
*/
public class DieClient
{
private static Die die1,die2;
public static void main(String[]args)
{
die1=Die。getInstance(1);
die2=Die。getInstance(2);
System。out。println(die1.dice());
System。out。println(die2.dice());
}
}
(2)无上限多例模式。例数目没有上限的多例模式叫无上限多例模式。
注意:由于没有上限的多例类对实例的数目是没有限制的,因此,虽然这种多例模式是单例模式的推广,但是这种多例类并不一定能够回到单例类。于是先不知道要创建多少个实例,因此,必然使用聚集管理所有的实例。
例子:购物车
import java。util。ArrayList;
import java。util。HashMap;
public class ShoppingCart{
private ShoppingCart shoppingCart=null;
//使用HashMap聚集管理所有的实例;
private static HashMap《String,ShoppingCart》instanse=new HashMap《String,ShoppingCart》();
//订单列表
private ArrayList《ItemOrder》orderedItems=null;
//更新器
private int readCount=0;
/ *同单例类一样,私有的构造函数保证外界无法直接将此类实例化
*
*/
private ShoppingCart(){
orderedItems=new ArrayList《ItemOrder》();
}
/*
*获取购物车,一个用户只能有一个购物车。有多少用户就有多少购物车。
**/
public synchronized static ShoppingCart getInstance(String user){
ShoppingCart shoppingCart=instanse。get(user);
if(shoppingCart……null){
shoppingCart=new ShoppingCart();
instanse。put(user,shoppingCart);
}
return shoppingCart;
}
/*
*用户退出登陆的时候,通过外部调用将购物车移除。
**/
public synchronized void removeShoppingCart(String key){
instanse。remove(key);
}
/*
*获取购物车中订单列表(orderedItems)
**/
public ArrayList《ItemOrder》getOrderedItems(){
readIn();
readOut();
return orderedItems;
}
/*
*管理订单。
*如果是旧订单则更新其数量。
*如果是新订单则添加到订单列表中。
**/
public void addItem(String itemId){
updateIn();
ItemOrder order;
for(int i=0;i0){
try{
wait();
}catch(Exception e){
}
}
}
private synchronized void readIn(){
readCount++;
}
private synchronized void readOut(){
readCount――;
notifyAll();
}
}
例子:购物车
import java。util。ArrayList;
import java。util。HashMap;
public class ShoppingCart{
private ShoppingCart shoppingCart=null;
//使用HashMap聚集管理所有的实例;
private static HashMap《String,ShoppingCart》instanse=new HashMap《String,ShoppingCart》();
//订单列表
private ArrayList《ItemOrder》orderedItems=null;
//更新器
private int readCount=0;
/ *同单例类一样,私有的构造函数保证外界无法直接将此类实例化
*
*/
private ShoppingCart(){
orderedItems=new ArrayList《ItemOrder》();
}
/*
*获取购物车,一个用户只能有一个购物车。有多少用户就有多少购物车。
**/
public synchronized static ShoppingCart getInstance(String user){
ShoppingCart shoppingCart=instanse。get(user);
if(shoppingCart……null){
shoppingCart=new ShoppingCart();
instanse。put(user,shoppingCart);
}
return shoppingCart;
}
/*
*用户退出登陆的时候,通过外部调用将购物车移除。
**/
public synchronized void removeShoppingCart(String key){
instanse。remove(key);
}
/*
*获取购物车中订单列表(orderedItems)
**/
public ArrayList《ItemOrder》getOrderedItems(){
readIn();
readOut();
return orderedItems;
}
/*
*管理订单。
*如果是旧订单则更新其数量。
*如果是新订单则添加到订单列表中。
**/
public void addItem(String itemId){
updateIn();
ItemOrder order;
for(int i=0;i0){
try{
wait();
}catch(Exception e){
}
}
}
private synchronized void readIn(){
readCount++;
}
private synchronized void readOut(){
readCount――;
notifyAll();
}
}