1. 程式人生 > >編程經常使用設計模式具體解釋--(上篇)(工廠、單例、建造者、原型)

編程經常使用設計模式具體解釋--(上篇)(工廠、單例、建造者、原型)

-a 裝飾器模式 nds support art 類的繼承 兩個 開放 lose

參考來自:http://zz563143188.iteye.com/blog/1847029

一、設計模式的分類

整體來說設計模式分為三大類:

創建型模式。共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。

結構型模式,共七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。

行為型模式,共十一種:策略模式、模板方法模式、觀察者模式、叠代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。


二、設計模式的六大原則

1、開閉原則(Open Close Principle)

開閉原則就是說對擴展開放,對改動關閉

在程序須要進行拓展的時候。不能去改動原有的代碼。實現一個熱插拔的效果。所以一句話概括就是:為了使程序的擴展性好,易於維護和升級。

想要達到這種效果。我們須要使用接口和抽象類,後面的詳細設計中我們會提到這點。

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

裏氏代換原則(Liskov Substitution Principle LSP)面向對象設計的基本原則之中的一個。

裏氏代換原則中說,不論什麽基類能夠出現的地方,子類一定能夠出現。 LSP是繼承復用的基石,僅僅有當衍生類能夠替換掉基類。軟件單位的功能不受到影響時,基類才幹真正被復用,而衍生類也能夠在基類的基礎上添加新的行為。

裏氏代換原則是對“開-閉”原則的補充。實現“開-閉”原則的關鍵步驟就是抽象化。而基類與子類的繼承關系就是抽象化的詳細實現,所以裏氏代換原則是對實現抽象化的詳細步驟的規範。—— From Baidu 百科

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

這個是開閉原則的基礎,詳細內容:真對接口編程,依賴於抽象而不依賴於詳細。

4、接口隔離原則(Interface Segregation Principle)

這個原則的意思是:使用多個隔離的接口。比使用單個接口要好。還是一個減少類之間的耦合度的意思,從這兒我們看出,事實上設計模式就是一個軟件的設計思想,從大型軟件架構出發。為了升級和維護方便。

所以上文中多次出現:減少依賴,減少耦合。

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

為什麽叫最少知道原則。就是說:一個實體應當盡量少的與其它實體之間發生相互作用,使得系統功能模塊相對獨立。

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

原則是盡量使用合成/聚合的方式,而不是使用繼承。


三、Java的23中設計模式

從這一塊開始,我們具體介紹Java中23種設計模式的概念。應用場景等情況,並結合他們的特點及設計模式的原則進行分析。

1、工廠方法模式(Factory Method)

建立一個工廠類,對實現了同一接口的一些類進行實例的創建。經常使用用法

public interface Sender {  
    public void Send();  
}  

public class MailSender implements Sender {  
    @Override  
    public void Send() {  
        System.out.println("this is mailsender!");  
    }  
}  

public class SmsSender implements Sender {  
  
    @Override  
    public void Send() {  
        System.out.println("this is sms sender!");  
    }  
}  

public class SendFactory {  
      
    public static Sender produceMail(){  
        return new MailSender();  
    }  
      
    public static Sender produceSms(){  
        return new SmsSender();  
    }  
} 

2、抽象工廠模式(Abstract Factory)

工廠方法模式有一個問題就是,類的創建依賴工廠類,也就是說,假設想要拓展程序。必須對工廠類進行改動,這違背了閉包原則,所以,從設計角度考慮,有一定的問題,怎樣解決?就用到抽象工廠模式,創建多個工廠類,這樣一旦須要添加新的功能,直接添加新的工廠類就能夠了。不須要改動之前的代碼。

提供一個工廠類接口:

public interface Provider {  
    public Sender produce();  
} 

兩個工廠類:

public class SendMailFactory implements Provider {  
      
    @Override  
    public Sender produce(){  
        return new MailSender();  
    }  
}  

public class SendSmsFactory implements Provider{  
  
    @Override  
    public Sender produce() {  
        return new SmsSender();  
    }  
} 

事實上這個模式的優點就是。假設你如今想添加一個功能:發及時信息,則僅僅需做一個實現類。實現Sender接口,同一時候做一個工廠類。實現Provider接口,就OK了,無需去修改現成的代碼。

這樣做,拓展性較好!

可是麻煩....


3、單例模式(Singleton

單例對象(Singleton)是一種經常使用的設計模式。在Java應用中,單例對象能保證在一個JVM中。該對象僅僅有一個實例存在。

這種模式有幾個優點:

1、某些類創建比較頻繁,對於一些大型的對象,這是一筆非常大的系統開銷。

2、省去了new操作符。減少了系統內存的使用頻率,減輕GC壓力。

3、有些類如交易所的核心交易引擎。控制著交易流程,假設該類能夠創建多個的話,系統全然亂了。(比方一個軍隊出現了多個司令員同一時候指揮。肯定會亂成一團)。所以僅僅有使用單例模式。才幹保證核心交易server獨立控制整個流程。

一個比較完好的單例類:

public class Singleton {  
  
    /* 私有構造方法。防止被實例化 */  
    private Singleton() {  
    }  
  
    /* 此處使用一個內部類來維護單例,<span style="font-family: Arial; font-size: 14px; line-height: 26px; ">JVM內部的機制可以保證當一個類被載入的時候。這個類的載入過程是線程相互排斥的。</span> */  
    private static class SingletonFactory {  
        private static Singleton instance = new Singleton();  
    }  
  
    /* 獲取實例 */  
    public static Singleton getInstance() {  
        return SingletonFactory.instance;  
    }  
} 


4、建造者模式(Builder)

工廠類模式提供的是創建單個類的模式。而建造者模式則是將各種產品集中起來進行管理,用來創建復合對象。所謂復合對象就是指某個類具有不同的屬性,類似於多個工廠模式一起用。多了個導演類,

導演類:負責調用適當的建造者來組建產品,導演類一般不與產品類發生依賴關系,與導演類直接交互的是建造者類。

一般來說,導演類被用來封裝程序中易變的部分

public class Builder {  
    private List<Sender> list = new ArrayList<Sender>();  
      
    public void produceMailSender(int count){  
        for(int i=0; i<count; i++){  
            list.add(new MailSender());  
        }  
    }  
      
    public void produceSmsSender(int count){  
        for(int i=0; i<count; i++){  
            list.add(new SmsSender());  
        }  
    }  
}  

5、原型模式(Prototype)

該模式的思想就是將一個對象作為原型。對其進行復制、克隆,產生一個和原對象類似的新對象。簡化創建過程,節省性能

public class Prototype implements Cloneable, Serializable {  
    /* 淺復制 */  
    public Object clone() throws CloneNotSupportedException {  
        Prototype proto = (Prototype) super.clone();  
        return proto;  
    }  
  
    /* 深復制 */  
    public Object deepClone() throws IOException, ClassNotFoundException {  
  
        /* 寫入當前對象的二進制流 */  
        ByteArrayOutputStream bos = new ByteArrayOutputStream();  
        ObjectOutputStream oos = new ObjectOutputStream(bos);  
        oos.writeObject(this);  
  
        /* 讀出二進制流產生的新對象 */  
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());  
        ObjectInputStream ois = new ObjectInputStream(bis);  
        return ois.readObject();  
    }  
}  



編程經常使用設計模式具體解釋--(上篇)(工廠、單例、建造者、原型)