读书人

设计形式-单例模式(二)登记式

发布时间: 2012-09-08 10:48:07 作者: rapoo

设计模式--单例模式(二)登记式

本文是设计模式学习笔记的第二篇文章,主要分析的是单例模式。包括懒汉式,饿汉式,登记式,以及懒汉式的改进型,还有一个关于读取propertoes配置文件的实例。现在看来要写四节了。这是第二节,上一节分析了最基本的懒汉式和饿汉式,这次我们来看一下登记式。

登记式实际对一组单例模式进行的维护,主要是在数量上的扩展,通过map我们把单例存进去,这样在调用时,先判断该单例是否已经创建,是的话直接返回,不是的话创建一个登记到map中,再返回。对于数量又分为固定数量和不固定数量的。下面采用的是不固定数量的方式,在getInstance方法中加上参数(string name)。然后通过子类继承,重写这个方法将name传进去。让我们看看代码吧。


首先是父类:

        /** * 登记式单例模式 * MySingleton2 */public static void myprint3(){System.out.println("-----------------登记式单例模式----------------");System.out.println("第一次取得实例(登记式)");MySingleton3 s1 = MySingleton3.getInstance(null);System.out.println(s1);System.out.println("第二次取得实例(登记式)");MySingleton3Childa s3 = MySingleton3Childa.getInstance();System.out.println(s3);System.out.println(s3.about());System.out.println("第三次取得实例(登记式)");MySingleton3Childb s4 = MySingleton3Childb.getInstance();System.out.println(s4);System.out.println(s4.about());System.out.println("第四次取得实例(非正常直接new子类的构造方法)");MySingleton3Childb s5 = new MySingleton3Childb();System.out.println(s5);System.out.println(s5.about());System.out.println("输出父类中Map保存的所有单例,可以看出,直接new出来的实例并没有存在Map中");System.out.println(s1.getMap());System.out.println();}/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stub//懒汉式//myprint();//饿汉式//myprint2();//懒汉式改进//myprint2a();//登记式myprint3();}



先让我们看下输出结果:

-----------------登记式单例模式----------------
第一次取得实例(登记式)
-->name不存在,name赋值等于com.xq.mysingleton.MySingleton3
-->name对应的值不存在,开始创建
-->私有化构造函数被调用,创建实例中
-->返回name对应的值
com.xq.mysingleton.MySingleton3@6e1408
第二次取得实例(登记式)
-->name对应的值不存在,开始创建
-->私有化构造函数被调用,创建实例中
-->返回name对应的值
com.xq.mysingleton.MySingleton3Childa@f62373
---->我是MySingleton3的第一个子类MySingleton3Childa
第三次取得实例(登记式)
-->name对应的值不存在,开始创建
-->私有化构造函数被调用,创建实例中
-->返回name对应的值
com.xq.mysingleton.MySingleton3Childb@1f33675
---->我是MySingleton3的第二个子类MySingleton3Childb
第四次取得实例(非正常直接new子类的构造方法)
-->私有化构造函数被调用,创建实例中
com.xq.mysingleton.MySingleton3Childb@7c6768
---->我是MySingleton3的第二个子类MySingleton3Childb
输出父类中Map保存的所有单例,可以看出,直接new出来的实例并没有存在Map中
{com.xq.mysingleton.MySingleton3Childa=com.xq.mysingleton.MySingleton3Childa@f62373, com.xq.mysingleton.MySingleton3Childb=com.xq.mysingleton.MySingleton3Childb@1f33675, com.xq.mysingleton.MySingleton3=com.xq.mysingleton.MySingleton3@6e1408}


有点乱哈,让我们分析下。

先后总共我们创建创建了4个单例。

第一种情况是我们直接调用父类的方法,传入空值,结果调用父类的方法创建一个实例,并且登记在map中,后期打印可知为

com.xq.mysingleton.MySingleton3=com.xq.mysingleton.MySingleton3@6e1408

第二种情况是我们调用子类a的方法,由a创建一个实例并且登录在父类的map中。后期打印可知为

com.xq.mysingleton.MySingleton3Childa=com.xq.mysingleton.MySingleton3Childa@f62373

第三种情况是我们调用子类b的方法,由a创建一个实例并且登录在父类的map中。后期打印可知为

com.xq.mysingleton.MySingleton3Childb=com.xq.mysingleton.MySingleton3Childb@1f33675

第四种情况是我们直接调用子类b的构造函数,如上虽然我们创建了一个实例com.xq.mysingleton.MySingleton3Childb@7c6768,但是并没有存在map中。

其实这也是这个解决方案的缺点,因为我们将父类构造方法对外公开了(protected)。。。。有一个解决方法是把你的单例类放到一个外在的包中,以便在其它包中的类(包括缺省的包)无法实例化一个单例类。


相关链接:

设计模式--单例模式(一)懒汉式和饿汉式设计模式--单例模式(二)登记式设计模式--单例模式(三)改进型懒汉式设计模式--单例模式(四)单例模式实例配置 Properties




读书人网 >软件开发

热点推荐