1. 程式人生 > >java 設計模式(單例,享元,策略)

java 設計模式(單例,享元,策略)

讀書不覺已春深,一寸光陰一寸金。

java的設計模式大體上分為三大類:

  • 建立型模式(5種):工廠方法模式,抽象工廠模式,單例模式,建造者模式,原型模式。

  • 結構型模式(7種):介面卡模式,裝飾器模式,代理模式,外觀模式,橋接模式,組合模式,享元模式。

  • 行為型模式(11種):策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、直譯器模式。

設計模式遵循的原則有6個:

1、開閉原則(Open Close Principle)

  對擴充套件開放,對修改關閉

2、里氏代換原則(Liskov Substitution Principle)

  只有當衍生類可以替換掉基類,軟體單位的功能不受到影響時,基類才能真正被複用,而衍生類也能夠在基類的基礎上增加新的行為。

3、依賴倒轉原則(Dependence Inversion Principle)

  這個是開閉原則的基礎,對介面程式設計,依賴於抽象而不依賴於具體。

4、介面隔離原則(Interface Segregation Principle)

  使用多個隔離的藉口來降低耦合度。

5、迪米特法則(最少知道原則)(Demeter Principle)

  一個實體應當儘量少的與其他實體之間發生相互作用,使得系統功能模組相對獨立。

6、合成複用原則(Composite Reuse Principle)

  原則是儘量使用合成/聚合的方式,而不是使用繼承。繼承實際上破壞了類的封裝性,超類的方法可能會被子類修改。

 

 

單例模式(Singleton)

餓漢模式 ———>>沒有呼叫,就生成單例物件,比較著急

餓漢模式 ———>>沒有呼叫,就不生成單例物件,只有呼叫的時候才生成單例物件,不著急。

首先,用一般的已有的知識實單例

           在內部建立一個例項,構造器全部設定為private,所有方法均在該例項上改動,在建立上要注意類的例項化只能執行一次,可以採用許多種方法來實現,如Synchronized關鍵字,或者利用內部類等機制來實現。

方法一:構造方法私有,自己建立例項物件給呼叫(餓漢模式)

public class Singleton1 {//餓漢模式
    //單例1:讓構造方法私有,自己new物件給呼叫
    private Singleton1(){

    }//構造方法私有
    private static final Singleton1 singleton1 = new Singleton1();
     public static Singleton1 getInstance() {
        return singleton1;
    }//給出例項去呼叫
}

方法二:懶漢模式,呼叫的時候在new,執行緒不安全,上鎖。

public class Singleton2 {//懶漢模式,用到才建立,不用不建立
    private Singleton2(){
    }
    private static Singleton2 S2;
    //執行緒安全,上鎖
    public static synchronized Singleton2 getInstance(){
        //通過判斷,只new一次物件。
        if (S2 == null){
            S2 =new Singleton2();
        }
        return S2;
    }
}

方法三:直接用列舉類實現單例

public enum Singleton3 {
    SI3;
}

方法四:靜態內部類

public class Singleton4 {
    private Singleton4(){//懶漢模式,JVM管理內部類,不會出現執行緒安全
        System.out.println("構造");
    }
    static{
        System.out.println("S4");
    }
    //靜態內部類
    private static class Hoder{
        static {
            System.out.println("Hoder ");
        }
        static Singleton4 S4 = new Singleton4();
    }
    public static Singleton4 getInstance() {
        return Hoder.S4;
    }
    public static void test(){
        System.out.println("test");
    }
    
}

享元模式(Flyweight)

提倡重用已有的物件,而不是建立新的物件
Integer的享元範圍 -128 ~ 127
Byte, Short, Charater, Long
連線池--對資料庫連線物件進行了重用

策略模式(Strategy)

ava 集合或陣列的排序演算法
Collections.sort
Arrays.sort
基本型別 雙基點快速排序
物件型別 TimSort (早期使用歸併排序)
規模小 插入排序排序演算法是固定的,排序的規則能否固定?--》 不能  
把排序的規則抽取出來,形成比較器介面(Comparator),不同比較器的實現就稱為策略

意圖:定義一系列的演算法,把它們一個個封裝起來, 並且使它們可相互替換。

主要解決:在有多種演算法相似的情況下,使用 if...else 所帶來的複雜和難以維護。

何時使用:一個系統有許多許多類,而區分它們的只是他們直接的行為。

如何解決:將這些演算法封裝成一個一個的類,任意地替換。

關鍵程式碼:實現同一個介面。

應用例項: 1、諸葛亮的錦囊妙計,每一個錦囊就是一個策略。 2、旅行的出遊方式,選擇騎自行車、坐汽車,每一種旅行方式都是一個策略。 3、JAVA AWT 中的 LayoutManager。

優點: 1、演算法可以自由切換。 2、避免使用多重條件判斷。 3、擴充套件性良好。

缺點: 1、策略類會增多。 2、所有策略類都需要對外暴露。

使用場景: 1、如果在一個系統裡面有許多類,它們之間的區別僅在於它們的行為,那麼使用策略模式可以動態地讓一個物件在許多行為中選擇一種行為。 2、一個系統需要動態地在幾種演算法中選擇一種。 3、如果一個物件有很多的行為,如果不用恰當的模式,這些行為就只好使用多重的條件選擇語句來實現。

注意事項:如果一個系統的策略多於四個,就需要考慮使用混合模式,解決策略類膨脹的問題。