java設計模式之原型模式

一、原型模式的定義
原型模式:用原型實例指定建立對象的種類,並經過拷貝這些原型建立新的對象。
原型模式的核心是一個clone方法,被拷貝對象須要實現cloneable接口並重寫clone()方法。數據庫

二、代碼示例數組

 

 

/**
 * 廣告信模板代碼
 *
 */
public class AdvTemplate {
    
    //廣告信名稱
    private String advSubject = "XX銀行國慶信用卡抽獎活動";
    //廣告信內容
    private String advContext = "國慶抽獎活動通知: 只要刷卡就送你一百萬! ...";
    //取得廣告信的名稱
    public String getAdvSubject(){
        return this.advSubject;
    }
    //取得廣告信的內容
    public String getAdvContext(){
        return this.advContext;
    }
}
/**
 * 郵件類代碼
 *
 */
public class Mail implements Cloneable {

    //收件人
    private String receiver;
    //郵件名稱
    private String subject;
    //稱謂
    private String appellation;
    //郵件內容
    private String contxt;
    //郵件的尾部, 通常都是加上"XXX版權全部"等信息
    private String tail;
    //構造函數
    public Mail(AdvTemplate advTemplate){
        this.contxt = advTemplate.getAdvContext();
        this.subject = advTemplate.getAdvSubject();
    }
    
    @Override
    protected Mail clone() {
        Mail mail = null;
        try {
            mail = (Mail) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return mail;
    }

    public String getReceiver() {
        return receiver;
    }
    public void setReceiver(String receiver) {
        this.receiver = receiver;
    }
    public String getSubject() {
        return subject;
    }
    public void setSubject(String subject) {
        this.subject = subject;
    }
    public String getAppellation() {
        return appellation;
    }
    public void setAppellation(String appellation) {
        this.appellation = appellation;
    }
    public String getContxt() {
        return contxt;
    }
    public void setContxt(String contxt) {
        this.contxt = contxt;
    }
    public String getTail() {
        return tail;
    }
    public void setTail(String tail) {
        this.tail = tail;
    }
}
/**
 * 場景類
 *
 */
public class Client {

    //發送帳單的數量, 這個值是從數據庫中得到
    private static int MAX_COUNT = 6;
    public static void main(String[] args) {
        //模擬發送郵件
        int i=0;
        //把模板定義出來, 這個是從數據庫中得到
        Mail mail = new Mail(new AdvTemplate());
        mail.setTail("XX銀行版權全部");
        while(i < MAX_COUNT){
            //如下是每封郵件不一樣的地方
            /*mail.setAppellation(getRandString(5) + " 先生( 女士) ");
            mail.setReceiver(getRandString(5) + "@" + getRandString(8) + ".com");*/
            Mail cloneMail = mail.clone();
            cloneMail.setAppellation(getRandString(5) + " 先生( 女士) ");
            cloneMail.setReceiver(getRandString(5) + "@" + getRandString(8) + ".com");
            //而後發送郵件
            sendMail(cloneMail);
            i++;
        }
    }
    //發送郵件
    public static void sendMail(Mail mail){
        System.out.println("標題: " + mail.getSubject() + "\t收件人:" + 
                mail.getReceiver() + "\t...發送成功! ");
    }
    //得到指定長度的隨機字符串
    public static String getRandString(int maxLength){
        String source ="abcdefghijklmnopqrskuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        StringBuffer sb = new StringBuffer();
        Random rand = new Random();
        for(int i = 0; i < maxLength; i++){
            sb.append(source.charAt(rand.nextInt(source.length())));
        }
        return sb.toString();
    }
}

三、原型模式優勢安全

性能優良
原型模式是在內存二進制流的拷貝,要比直接new一個對象性能好不少,特別是要在一個循環體內產生大量的對象時,原型模式能夠更好地體現其優勢。
逃避構造函數的約束
這既是它的優勢也是缺點,直接在內存中拷貝,構造函數是不會執行的。優勢就是減小了約束,缺點也是減小了約束,須要你們在實際應用時考慮。
四、原型模式的使用場景
資源優化場景
類初始化須要消化很是多的資源,這個資源包括數據、硬件資源等。
性能和安全要求的場景
經過new產生一個對象須要很是繁瑣的數據準備或訪問權限,則可使用原型模式。
一個對象多個修改者的場景
一個對象須要提供給其餘對象訪問,並且各個調用者可能都須要修改其值時,能夠考慮使用原型模式拷貝多個對象供調用者使用。
在實際項目中,原型模式不多單獨出現,通常是和工廠方法模式一塊兒出現,經過clone的方法建立一個對象,而後由工廠方法提供給調用者。
五、原型模式的注意事項
構造函數不會被執行
執行clone()方法時,原型對象的構造函數不會被執行。
淺拷貝和深拷貝
淺拷貝:clone()方法只拷貝對象自己,對象內部的數組、引用對象等都不拷貝(基本類型和string類型會被拷貝),仍是指向原生對象的內部元素地址。
深拷貝:原生對象全部內容全拷貝,互不影響。
clone與final兩個冤家
要使用clone方法, 類的成員變量上不要增長final關鍵字。app

相關文章
相關標籤/搜索