什么是設計模式?常用的設計模式有哪些?


設計模式就是經過前人無數次的實踐總結出的,設計過程中可以反復使用的、可以解決特定問題的設計方法。

單例(飽漢模式、飢漢模式)

1、構造方法私有化,讓出了自己類中能創建外其他地方都不能創建

2、在自己的類中創建一個單實例(飽漢模式是一出來就創建創建單實例,而飢漢模式需要的時候才創建

3、提供一個方法獲取該實例對象(創建時需要進行方法同步)

工廠模式:Spring IOC就是使用了工廠模式.

       對象的創建交給一個工廠去創建。

代理模式:Spring AOP就是使用的動態代理。

 

單例設計模式精講

定義:保證一個類只有一個實例,並且提供一個全局訪問點

場景:線程池,數據庫連接池

實現方式:   1.懶漢模式(只有使用的時候,再進行初始化,延遲加載)

      2.餓漢模式

      3.靜態內部類

      4.反射攻擊

      6.序列化

      7.jdk源碼

1.懶漢模式實現的寫法

public class SingletonTest {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                LazySingleton lazySingleton = LazySingleton.getInstance();
                System.out.println(lazySingleton);
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                LazySingleton lazySingleton = LazySingleton.getInstance();
                System.out.println(lazySingleton);
            }
        }).start();
        //兩個線程打印出來的線程實例是同一個,說明是單例
    }
}
//使用的時候才開始實例化,JVM中一個實例
class LazySingleton {
    private volatile static LazySingleton instance;

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

    private LazySingleton() {
    }

}

 2.餓漢模式

在類加載階段完成了實例的初始化,通過類加載機制來保證線程的安全

       類的加載過程

      1加載=》加載對應的二進制文件,並且在方法區創建對應的數據結構

       連接 :a.驗證  b.准備  c.解析

       初始化:給靜態屬性賦值

public class HungrySingletonTest {
    public static void main(String[] args) {
        HungrySingleton hungrySingleton = HungrySingleton.getInstance();
    }
}

class HungrySingleton {
    private static HungrySingleton instance = new HungrySingleton();
    public static HungrySingleton getInstance() {
        return instance;
    }
    private HungrySingleton() { }
}

 3.基於靜態內部類的單例

public class AntiTest {
    public static void main(String[] args) throws NoSuchMethodException,IllegalAccessException, InvocationTargetException, InstantiationException{
        InnerClassSingleton instance = InnerClassSingleton.getInstance();
        System.out.println(instance);
        
        //拋出異常,單例,不允許有多個實例
        Constructor<InnerClassSingleton>   declaredConstructor  = InnerClassSingleton.class.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
        InnerClassSingleton innerClassSingleton = declaredConstructor.newInstance();
        System.out.println(innerClassSingleton);
    }
}

class InnerClassSingleton{

    static class InnerClass{
        private static InnerClassSingleton instance = new InnerClassSingleton();
    }
    public static InnerClassSingleton getInstance(){
        return InnerClass.instance;
    }
    private InnerClassSingleton(){
        if ((InnerClass.instance!=null)){
            throw new RuntimeException("單例類,不允許多個實例!");
        }
    }
}

 4.枚舉單例

public class EnumSingletonTest{
    public static void main(String[] args) {
        EnumSingleton instance = EnumSingleton.INSTANCE;
        EnumSingleton instance1 = EnumSingleton.INSTANCE;
        System.out.println(instance==instance1);//true
        instance.print();//        149928006
        instance1.print();//        149928006
    }
}
enum EnumSingleton {
    INSTANCE;
    public void print(){
        System.out.println(this.hashCode());
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM