程序员人生 网站导航

读秦小波《设计模式之禅》 -- 单例模式

栏目:框架设计时间:2015-01-04 08:54:43

      新年第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



------分隔线----------------------------
------分隔线----------------------------

最新技术推荐