1. 程式人生 > >【面試題】設計模式相關

【面試題】設計模式相關

1.單例設計模式

  • 使用設計模式為了程式碼複用,增加可維護性。

  • 設計模式的六大原則:開閉原則、里氏代換原則、依賴倒轉原則、介面隔離原則、迪米特法則(最少知道原則)、合成/聚合複用原則

  • Singleton(建立):保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。如印表機

  • 餓漢式單例模式

//餓漢模式:執行緒安全,耗費資源。
public class HugerSingletonTest {
    //該物件的引用不可修改。還可以將物件的建立放到靜態程式碼塊中。
    private static final HugerSingletonTest ourInstance = new HugerSingletonTest();

    public
static HugerSingletonTest getInstance() { return ourInstance; } private HugerSingletonTest() { } }
  • 懶漢式:非執行緒安全
public class Singleton {
    private static Singleton ourInstance;

    public static Singleton getInstance() {
        if (null == ourInstance) {
            ourInstance = new
Singleton(); } return ourInstance; } private Singleton() { } }
  • 懶漢式,執行緒安全:給方法加鎖,消耗資源。
public class Singleton {
    private static Singleton ourInstance;

    public synchronized static Singleton getInstance() {
        if (null == ourInstance) {
            ourInstance = new
Singleton(); } return ourInstance; } private Singleton() { } }
  • 懶漢式,執行緒安全:雙重檢查鎖。
public class Singleton {
    private static Singleton ourInstance;

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

    private Singleton() {
    }
}
  • 分析:JVM會進行指令重排序,原本的步驟應該是先給 singleton 分配記憶體,然後呼叫 Singleton 的建構函式來初始化成員變數,形成例項,最後將singleton物件指向分配的記憶體空間,但有可能步驟會打亂,就會出現例項非空但沒有初始化,丟擲異常。將singleton宣告成 volatile ,就可以解決該問題。

  • 懶漢式,執行緒安全:靜態內部類

public class Singleton {
    private static class SingletonHodler {
        private static Singleton ourInstance = new Singleton();
    }

    public synchronized static Singleton getInstance() {
        return SingletonHodler.ourInstance;
    }

    private Singleton() {
    }
}
  • 懶漢式,執行緒安全:列舉
enum SingletonTest {  
    INSTANCE;  
}
  • 單例模式在JDK8原始碼中的使用:Runtime.getRuntime()方法(餓漢式單例模式)

2.介面卡設計模式

  • 介面卡模式(結構)中的角色:目標介面(Target):客戶所期待的介面、需要適配的類(Adaptee)、介面卡(Adapter)。

  • 物件介面卡(採用物件組合方式實現)

//介面卡類實現了目標介面
public class Adapter implements Target{
    private Adaptee adaptee ;
    public Adapter() {
        super();
        this.adaptee = new Adaptee();
    }
    @Override
    public void getHeadset2() {
        adaptee.getHeadset3();
    }
    public static void main(String args[]){
        Target target = new Adapter();
        //表面上呼叫的是2孔插座方法,但其實呼叫的三孔插座方法。
        target.getHeadset2();
    }
}
interface Target{
    //兩孔插座
    void getHeadset2();
}
class Adaptee{
    public void getHeadset3(){
        System.out.println("我是三孔插座!");
    }
}
  • 介面卡模式在JDK原始碼的使用
    • Arrays.asList(),其中Arrays是目標類,內部類ArrayList是介面卡類,而Objects.requireNonNull(array);需要適配的類。
    • InputStreamReader .read(),其中Reader 是目標類,InputStreamReader是介面卡類,而StreamDecoder 是需要適配的類。

3.模板方法設計模式

  • 模板方法設計模式(行為)使用了繼承機制,在抽象類中定義一個模板方法,該方法引用了若干個抽象方法(由子類實現)或具體方法(子類可以覆蓋重寫)

  • 模板方法設計模式在JDK原始碼的使用:Collections.sort()、InputStream.read()等



本人才疏學淺,若有錯,請指出,謝謝!
如果你有更好的建議,可以留言我們一起討論,共同進步!
衷心的感謝您能耐心的讀完本篇博文!