【設(shè)計模式】之單例模式


作者:xcbeyond
瘋狂源自夢想,技術(shù)成就輝煌!微信公眾號:《程序猿技術(shù)大咖》號主,專注后端開發(fā)多年,擁有豐富的研發(fā)經(jīng)驗,樂于技術(shù)輸出、分享,現(xiàn)階段從事微服務(wù)架構(gòu)項目的研發(fā)工作,涉及架構(gòu)設(shè)計、技術(shù)選型、業(yè)務(wù)研發(fā)等工作。對于Java、微服務(wù)、數(shù)據(jù)庫、Docker有深入了解,并有大量的調(diào)優(yōu)經(jīng)驗。 







  單例模式(Singleton  Pattern):

  確保某個類只有一個對象。單例類的構(gòu)造器是私有的(private),避免外界利用構(gòu)造器直接創(chuàng)建出任意多的實例。由于構(gòu)造器是private的,因此單例類是不能被繼承。

特點:

1>、單例類只能有一個實例。

2>、單例類必須自己創(chuàng)建自己的唯一實例。

3>、單例類必須給所有其他對象提供這一實例。

單例模式分三種:懶漢式單例、餓漢式單例、登記式單例三種。

1、餓漢式單例

    package 單例模式;
    /**
     * 餓漢式單例:自己將自己實例化
     * 在這個類被加載時,靜態(tài)變量instance會被初始化,此時類的私有構(gòu)造器被調(diào)用,這時單例類的唯一實例就被創(chuàng)建了。
     * @author xcbeyond
     * @date 2012-5-1 上午11:56:26
     */
    public class EagerSingleton {
        private static final EagerSingleton instance = new                                                 EagerSingleton();
        //私有構(gòu)造器
        private EagerSingleton() {
        }
        
        public static EagerSingleton getInstance() {
            return instance;
        }
    }


 

2、懶漢式單例

        與餓漢式單例不同的是,懶漢式單例類在第一次被引用時將自己實例化。如果加載器是靜態(tài)的,那么在懶漢式單例類被加載時不會將自己實例化。

    package 單例模式;
    /**
     * 懶漢式單例
     * @author xcbeyond
     * @date 2012-5-1 下午12:23:54
     */
    public class LazySingleton {
        private static LazySingleton instance = null;
        
        //私有構(gòu)造器
        private LazySingleton(){
        }
        
        //靜態(tài)工廠方法,返回此類的唯一實例
        synchronized public static LazySingleton getInstance () {
            if(instance == null ) {
                instance = new LazySingleton();
            }
            return instance;
        }
    }


 

3、登記式單例

         為了克服餓漢式單例類和懶漢式單例類不可繼承的缺點,于是引入了登記式單例類。

    package 單例模式;
     
    import java.util.HashMap;
     
    /**
     * 登記式單例類:克服了餓漢式和懶漢式單例類的不可繼承的缺點。
     * @author xcbeyond
     * @date 2012-5-1 下午12:35:23
     */
    public class RegisterSingleton {
         private static HashMap reg = new HashMap();
        
        static {
            RegisterSingleton x = new RegisterSingleton();
            reg.put(x.getClass().getName(), x);
        }
        
        //保護(hù)的默認(rèn)構(gòu)造器
        protected RegisterSingleton () {
            
        }
        
        //靜態(tài)工廠方法,返回此類唯一的實例
        public static RegisterSingleton getInstance(String name) {
            if(name == null) {
                name = "RegisterSingleton";
            }
            if(reg.get(name)==null) {
                try{
                    reg.put(name, Class.forName(name).newInstance());
                }catch(Exception e) {
                    System.out.println("Error happened");
                }
            }
            return (RegisterSingleton)reg.get(name);
        }
    }