新年第一天,在这里首先要祝大家新年快乐!
这篇文章中,介绍的是非常重要,也是非常常用的一种设计模式 -- 单例模式。例如,我们在电脑上登录QQ的时候,同一个QQ号码就只能登录一次,而不可能出现一个号码可以登录两次的情况;再好像我现在听歌用的播放器,我也只能打开它一次,当它在运行的时候,我不能够同时运行两个播放器客户端。。。等等的这些模式都是单例的,即它能保证一个类就只有一个实例对象。
这里运用书中的例子去解释构造单例的方法。
一个国家需要有一个皇帝,并且这个皇帝就只能有一个,那么,很显然,它是单例的。我们需要构造一个皇帝类,且这个皇帝类只能有一个实例对象,那么,这里就会出现一个限制,即这个类的构造方法需要是私有的(private),否则,我们可以任意的生成对象。且这个类需要有一个静态方法(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..."); } }
这个类的实现就是利用到单例模式,当然,这里只是单例模式的一种实现方式。
我们需要一个测试函数,测试下这个单例模式是否好用,这里,场景是有几个大臣找皇帝,然后,每一个大臣找到的都是同一个皇帝。
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) { /*获取的实例对象都是同一个*/ __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...
下面,看下类图是怎样的,很简单,没有继承关系之类的
书中从单例模式又引申出了一个叫 “多例模式” 的设计方法,即一个类能产生多个对象,但是对象的个数是有限制的。
也同样是皇帝的例子,只是这个例子中出现了多个皇帝,每个大臣可能找到的是不同的皇帝。
好吧,这个也是很容易实现的:
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
时间: 2024-10-25 10:04:54