zoukankan      html  css  js  c++  java
  • 独领风骚:单例模式

    作者:Jeff Lee 出处:http://www.cnblogs.com/Alandre/ 欢迎转载,也请保留这段声明。谢谢!

    系列文章:[传送门]

     

      单例模式(Singleton)可以说是最简单的模式,对.net来说,因为不需要考虑到垃圾回收机制,实现起来很简单,但是对于没有提供内存管理的平台来说,比如C++,因为单例模式只考虑创建对象,所以使用的时候要考虑全面些。Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。

    案例有如下:

        单一的程序属性文件
        一个系统唯一的回收站

    单例模式的结构

        

      1.单例类只有一个实例
      2.单例类必须自己创建自己唯一的实例
      2单例类必须给所有其他对象提供这个实例

    java中实现单例模式

    饿汉单例类

    /**
     * 饿汉单例类
     * #由于构造函数是私有的,此类不会被继承,也不会被外界直接创建任意多的实例。
     * @author Li
     */
    public class EagerSingleton {
        private static final EagerSingleton m_instance =  new EagerSingleton();
        
        /**
         * 私有的默认构造子
         */
        private EagerSingleton()
        {
        }
        
        /**
         * 静态工厂方法
         */
        public static EagerSingleton getInstance()
        {
            return m_instance;
        }
     
    }
    #由于构造函数是私有的,此类不会被继承,也不会被外界直接创建任意多的实例。

     

    懒汉式单例类

    public class Singleton {
      private static Singleton instance = null;
    
      public static synchronized Singleton getInstance() {
    
      if (instance==null)
        instance=new Singleton();
      return instance;   }
    
    }

     #synchronized:关键字,代表这个方法加锁

    #懒汉式的区别,只有第一次调用后才会有个实例出来。

    登记式单例类

    import java.util.HashMap;
    import java.util.Map;
    //登记式单例类.
    //类似Spring里面的方法,将类名注册,下次从里面直接获取。
    public class Singleton3 {
        private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();
        static{
            Singleton3 single = new Singleton3();
            map.put(single.getClass().getName(), single);
        }
        //保护的默认构造子
        protected Singleton3(){}
        //静态工厂方法,返还此类惟一的实例
        public static Singleton3 getInstance(String name) {
            if(name == null) {
                name = Singleton3.class.getName();
                System.out.println("name == null"+"--->name="+name);
            }
            if(map.get(name) == null) {
                try {
                    map.put(name, (Singleton3) Class.forName(name).newInstance());
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
            return map.get(name);
        }
        //一个示意性的商业方法
        public String about() {    
            return "Hello, I am RegSingleton.";    
        }    
        public static void main(String[] args) {
            Singleton3 single3 = Singleton3.getInstance(null);
            System.out.println(single3.about());
        }
    }

    .NET 单例实践

    .net中解决线程安全的问题也很简单,就是用lock锁。摘自我的小伙伴:http://www.cnblogs.com/xishuai/p/3509346.html

    public class SingletonTest
        {
            private static SingletonTest singleton;
            private static readonly object syncObject = new object();
            /// <summary>
            /// 构造函数必须是私有的
            /// 这样在外部便无法使用 new 来创建该类的实例
            /// </summary>
            private SingletonTest()
            { }
            /// <summary>
            /// 定义一个全局访问点
            /// 设置为静态方法
            /// 则在类的外部便无需实例化就可以调用该方法
            /// </summary>
            /// <returns></returns>
            public static SingletonTest getSingleton()
            {
                //这里可以保证只实例化一次
                //即在第一次调用时实例化
                //以后调用便不会再实例化
                //第一重 singleton == null
                if (singleton == null)
                {
                    lock (syncObject)
                    {
                        //第二重 singleton == null
                        if (singleton == null)
                        {
                            Console.WriteLine(String.Format("我是被线程:{0}创建的!", Thread.CurrentThread.Name));
                            singleton = new SingletonTest();
                        }
                    }
                }
                return singleton;
            }
        }

    总结 

      单例模式优点

        一、实例控制
          单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。
        二、灵活性
          因为类控制了实例化过程,所以类可以灵活更改实例化过程。
     

      单例模式缺点

        一、开销
          虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。
        二、可能的开发混淆
          使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。
        三、对象生存期
          不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除对象实例,但这样会导致单例类中出现悬浮引用。

    感谢及资源共享

        

        路上走来一步一个脚印,希望大家和我一起。

        感谢读者!很喜欢你们给我的支持。如果支持,点个赞。

        知识来源: http://book.douban.com/doulist/3942229/

     
  • 相关阅读:
    iOS
    iOS
    ios
    iOS
    ios
    ios
    iOS
    ios
    常用NSString的方法
    instancetype
  • 原文地址:https://www.cnblogs.com/Alandre/p/3674645.html
Copyright © 2011-2022 走看看