当前位置:编程学习 > JAVA >>

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

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


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


首先是父类:

[java] 
//采用Map配置多个单例 
public class MySingleton3 { 
     
    // 设立静态变量,直接创建实例 
    private static Map<String, MySingleton3> map = new HashMap<String, MySingleton3>(); 
         
    // -----受保护的-----构造函数,不能是私有的,但是这样子类可以直接访问构造方法了 
    //解决方式是把你的单例类放到一个外在的包中,以便在其它包中的类(包括缺省的包)无法实例化一个单例类。 
    protected MySingleton3() { 
        System.out.println("-->私有化构造函数被调用,创建实例中"); 
         
    } 
 
    // 开放一个公有方法,判断是否已经存在实例,有返回,没有新建一个在返回 
    public static MySingleton3 getInstance(String name) { 
        if (name == null) { 
            name = MySingleton3.class.getName(); 
            System.out.println("-->name不存在,name赋值等于"+MySingleton3.class.getName()); 
        } 
        if (map.get(name) == null) { 
            try { 
                System.out.println("-->name对应的值不存在,开始创建"); 
                map.put(name, (MySingleton3)Class.forName(name).newInstance()); 
            } catch (InstantiationException e) { 
                e.printStackTrace(); 
            } catch (IllegalAccessException e) { 
                e.printStackTrace(); 
            } catch (ClassNotFoundException e) { 
                e.printStackTrace(); 
            } 
        }else { 
            System.out.println("-->name对应的值存在"); 
        } 
        System.out.println("-->返回name对应的值"); 
        return map.get(name); 
    } 
     
    public Map<String, MySingleton3> getMap(){ 
        return map; 
    } 

然后写了俩个子类:
[java] 
public class MySingleton3Childa extends MySingleton3 { 
     
    public static MySingleton3Childa getInstance() { 
        return (MySingleton3Childa) MySingleton3Childa 
                .getInstance("com.xq.mysingleton.MySingleton3Childa"); 
    } 
 
    //随便写一个测试的方法 
    public String about() { 
        return "---->我是MySingleton3的第一个子类MySingleton3Childa"; 
    } 

[java]
public class MySingleton3Childb extends MySingleton3 { 
     
    static public MySingleton3Childb getInstance() { 
        return (MySingleton3Childb) MySingleton3Childb 
                .getInstance("com.xq.mysingleton.MySingleton3Childb"); 
    } 
 
    //随便写一个测试的方法 
    public String about() { 
        return "---->我是MySingleton3的第二个子类MySingleton3Childb"; 
    } 


然后是客户端代码,这回测试用例比较多哈:

[java] 
       /**
 * 登记式单例模式
 * 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(); 
    //懒汉式改进 
  

补充:软件开发 , Java ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,