读秦小波《设计模式之禅》 -- 单例模式
来源:程序员人生 发布时间:2015-01-04 08:54:43 阅读次数:3173次
新年第1天,在这里首先要祝大家新年快乐!
这篇文章中,介绍的是非常重要,也是非常经常使用的1种设计模式 -- 单例模式。例如,我们在电脑上登录QQ的时候,同1个QQ号码就只能登录1次,而不可能出现1个号码可以登录两次的情况;再好像我现在听歌用的播放器,我也只能打开它1次,当它在运行的时候,我不能够同时运行两个播放器客户端。。。等等的这些模式都是单例的,即它能保证1个类就只有1个实例对象。
这里应用书中的例子去解释构造单例的方法。
1个国家需要有1个皇帝,并且这个皇帝就只能有1个,那末,很明显,它是单例的。我们需要构造1个皇帝类,且这个皇帝类只能有1个实例对象,那末,这里就会出现1个限制,即这个类的构造方法需要是私有的(private),否则,我们可以任意的生成对象。且这个类需要有1个静态方法(static),当我们需要这个类的对象时,就能够利用这个方法去获得类对象。
好吧,看下具体的实现吧:
public class __Q_Y_Emperor {
/*这样设计可以保证它是线程安全的*/
private static __Q_Y_Emperor _Emperor = new __Q_Y_Emperor();
private __Q_Y_Emperor()
{
}
public static __Q_Y_Emperor __Q_Y_GetInstance()
{
return _Emperor;
}
public static void __Q_Y_Talk()
{
System.out.println("i am Qinyi Zhang...");
}
}
这个类的实现就是利用到单例模式,固然,这里只是单例模式的1种实现方式。
我们需要1个测试函数,测试下这个单例模式是不是好用,这里,场景是有几个大臣找皇帝,然后,每个大臣找到的都是同1个皇帝。
public class __Q_Y_EmperorMain {
/**
* @param args
*/
@SuppressWarnings("static-
access")
public static void main(String[] args) {
// TODO Auto-generated method stub
int _Minister = 5;
for (int i = 0; i != _Minister; ++i)
{
/*获得的实例对象都是同1个*/
__Q_Y_Emperor _Emperor = __Q_Y_Emperor.__Q_Y_GetInstance();
_Emperor.__Q_Y_Talk();
}
}
}
我们运行下这个主函数,得到以下的结果:
i am Qinyi Zhang...
i am Qinyi Zhang...
i am Qinyi Zhang...
i am Qinyi Zhang...
i am Qinyi Zhang...
下面,看下类图是怎样的,很简单,没有继承关系之类的
书中从单例模式又引伸出了1个叫 “多例模式” 的设计方法,即1个类能产生多个对象,但是对象的个数是有限制的。 也一样是皇帝的例子,只是这个例子中出现了多个皇帝,每一个大臣可能找到的是不同的皇帝。
好吧,这个也是很容易实现的:
public class __Q_Y_MultiEmperor {
private final static int _MaxNumOfEmperor = 3;
private static ArrayList<String> _EmperorName = new ArrayList<String>();
private static ArrayList<__Q_Y_MultiEmperor> _EmperorList = new ArrayList<>();
private static int _CurrentNumOfEmperor = 0;
private __Q_Y_MultiEmperor()
{
}
private __Q_Y_MultiEmperor(String _name)
{
_EmperorName.add(_name);
}
static
{
/*多例模式,对象个数是有限制的*/
for (int i = 0; i != _MaxNumOfEmperor; ++i)
{
_EmperorList.add(new __Q_Y_MultiEmperor("num " + (i + 1)));
}
}
public static __Q_Y_MultiEmperor __Q_Y_GetInstance()
{
Random _randrom = new Random();
_CurrentNumOfEmperor = _randrom.nextInt(_MaxNumOfEmperor);
return _EmperorList.get(_CurrentNumOfEmperor);
}
public static void __Q_Y_Talk()
{
System.out.println(_EmperorName.get(_CurrentNumOfEmperor));
}
}
测试函数:
public class __Q_Y_MultiMain {
/**
* @param args
*/
@SuppressWarnings("static-
access")
public static void main(String[] args) {
// TODO Auto-generated method stub
int _Minister = 10;
for (int i = 0; i != _Minister; ++i)
{
__Q_Y_MultiEmperor _Emperor = __Q_Y_MultiEmperor.__Q_Y_GetInstance();
_Emperor.__Q_Y_Talk();
}
}
}
类图:
最后,运行下这个例子吧:
num 3
num 2
num 2
num 2
num 3
num 1
num 2
num 2
num 1
num 1
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠