• 设计模式之Singleton模式


    当程序运行时,有时会希望在程序中,只能存在一个实例,为了达到目的,所以设计了Singleton模式,即单例模式。

    单例模式的特征:

    • 想确保任何情况下只存在一个实例
    • 想在程序上表现出只存在一个实例

    示例程序:

    • Singleton单例类
    package site.wangxin520.gof.singleton;
    
    /**
     * 单例模式获取单例对象的类
     * @author wangXgnaw
     *
     */
    public class Singleton {
        
        //将创建出来的对象设为静态的私有对象
        private static Singleton singleton=new Singleton();
        //将构造方法私有化,不允许外部类中使用new 去创建对象
        private Singleton(){}
        //对外提供一个静态方法,获取到对象,因为对象是静态的私有属性
        //所以是随着类的加载而加载的,并且只加载一次,这样一来,就只返回同一个对象了
        public static Singleton getInstance(){
            return singleton;
        }
        
    }
    • Singleton单例测试程序
    package site.wangxin520.gof.singleton;
    
    /**
     * 单例模式的测试类
     * @author wangXgnaw
     *
     */
    public class SingletonTest {
    
        public static void main(String[] args) {
            //使用getInstance获取实例化的方法,创建两个对象
            Singleton s1 = Singleton.getInstance();
            Singleton s2 = Singleton.getInstance();
            //==双等号,在判断对象的时候,是比较对象的地址值,如果地址值为一样的话,那么就代表,单例模式创建成功。
            if (s1==s2) {
                System.out.println("单例模式创建成功");
            }else {
                System.out.println("单例模式创建失败");
            }
            
        }
        
    }
    • 测试结果:

    image

    在单例模式中,需要注意的是,多线程情况下单例模式可能存在的问题,这里不做讨论。还有就是static关键字的用法——静态随着类加载而加载,且只加载一次。

    补充一个测试练习题:

    编写Triple类,实现最多只能生成三个实例,实例编号为0,1,2,并且可以通过getInstance(int id)方法来获取到该编号对应的实例:

    • Triple类
    package site.wangxin520.gof.singleton;
    
    import java.util.ArrayList;
    
    public class Triple {
        
        //建立一个静态的数组,用于保存创建的实例
        private static ArrayList<Triple> arr=new ArrayList<Triple>();
        
        //属性id
        private int id;
        
        //私有化构造函数
        private Triple(){}
        
        //通过id去获取对应的实例
        public static Triple getInstance(int id){
            try{
                //尝试从静态数组中获取,这里采用的是try catch接异常的方法
                Triple triple = arr.get(id);
                //如果数组中存在所需要的,那么就直接返回,否则抛异常
                return triple;
            }catch(Exception e){
                //调用getInstance()方法进行操作
                return getInstance();
            }
        }
        
        //没有参数,就不会造成异常的产生
        public static Triple getInstance(){
            //判断是否创建超过了3
            if(arr.size()<3){
                Triple t=new Triple();
                t.id=arr.size();
                arr.add(t);
                return t;
            }else{
                //如果创建超过了3个,那么就返回第一个实例s
               return getInstance(0);
            }
        }
        
    }
    • 测试类
    package site.wangxin520.gof.singleton;
    
    public class TripleTest {
        public static void main(String[] args) {
            
            Triple t1 = Triple.getInstance();
            Triple t2 = Triple.getInstance();
            Triple t3 = Triple.getInstance();
            Triple t4 = Triple.getInstance();
            
            System.out.println(t1==t2);
            System.out.println(t1==t3);
            System.out.println(t1==t4);
            System.out.println(t2==t3);
            System.out.println(t2==t4);
            System.out.println(t3==t4);
            
        }
    }
    • 结果

    image

    可见t1和t4是相同的,因为超过三个了,就直接返回第一个,getInstance()方法正常

    • 测试2
    package site.wangxin520.gof.singleton;
    
    public class TripleTest {
        public static void main(String[] args) {
            Triple t1 = Triple.getInstance(0);
            Triple t2 = Triple.getInstance(1);
            Triple t3 = Triple.getInstance(2);
            Triple t4 = Triple.getInstance(3);
            System.out.println(t1==t2);
            System.out.println(t1==t3);
            System.out.println(t1==t4);
            System.out.println(t2==t3);
            System.out.println(t2==t4);
            System.out.println(t3==t4);
            
        }
    }
    • 结果

    image

    同样的,当想要获取编号不在0,1,2三个里面的话,就会返回第0个,所以t4和t1是相同的。

  • 相关阅读:
    注意! javascript和jquery的方法不能混淆!
    Fatal error: Call to undefined function mysqli_connect() 的解决方法
    Js中的冒泡排序
    sql的key的类型分类
    C# 结构和类的区别
    C#泛型初识2
    Javascript面向对象全面剖析 —创建对象
    C#泛型(初识)
    C# 构造函数日志
    C#隐式和显示类型转换
  • 原文地址:https://www.cnblogs.com/wangxinblog/p/7608383.html
Copyright © 2020-2023  润新知