天天看點

設計模式-原型模式電子賬單使用多線程改進最後 深拷貝應用

設計模式-原型模式

用原型執行個體指定建立對象的種類,通過拷貝這些原型建立新的對象。

電子賬單

即,使用電子賬單

設計模式-原型模式電子賬單使用多線程改進最後 深拷貝應用
// 廣告信模闆
public class AdvTemplate {
    // 廣告信名稱
    private String advSubject = "XX活動";
    // 廣告内容
    private String advContext = "XX活動";
    // 取得廣告名稱
    public String getAdvSubject(){
        return this.advSubject;
    }
    // 取得廣告信内容
    public String getAdvContext(){
        return this.advContext;
    }
}           
// 郵件
public class Mail {
    // 收件人
    private String receiver;
    // 郵件名稱
    private String subject;
    // 稱謂
    private String appellation;
    // 郵件内容
    private String contxt;
    // 郵件尾部
    private String tail;
    // 構造函數
    public Mail(AdvTemplate advTemplate){
        this.contxt = advTemplate.getAdvContext();
        this.subject = advTemplat.getAdvSubject()
    }
    // get set方法
    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 getApplation(){
        return applation;
    }
    public void setApplation(String applation){
        this.appellation = applation
    }
    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("  ");
        while(i < MAX_COUNT){
            mail.setAppllation(getRandString(5) + "先生(女士)");
            mail.setReceiver(getRandString(5) + "@" + mail.getRandString() + ".com");
            // 發送郵件
            sendMail(mail);
            i++;
        }
    }
    // 發送郵件
    public static void sendMail(Mail mail){
        System.out.println("标題" + mail.getSubject() + "發送成功");
    }
    // 擷取指定長度的随機字元串
    public static String getRandString(int maxLength){
        String source = "abcdefghijklmnopqrstuvwxyz";
        // 緩沖區
        StringBuffer sb = new StringBuffer();
        // 随機數
        Random rand = new Random();
        // 進行循環
        for(int i = 0; i < maxLength; i++){
            // 進行随機取字元數
            sb.append(source.charAt(rand.nextlnt(source.length())));    // rand.nextInt()    生成僞随機數,放入到緩沖區内
        }
        return sb.toString();    // 傳回生成的僞字元串
    }
}           

使用多線程改進

由于是一個線程發送郵件過慢,使用多線程解決問題。

設計模式-原型模式電子賬單使用多線程改進最後 深拷貝應用

增加一個Cloneable接口

關于克隆

克隆用途

關于Cloneable 接口,用途和Serializable一樣為标記型接口,内部沒有方法和屬性,implements Cloneable 表示對象能被克隆,即能使用Object.clone()方法,

關于深淺拷貝

這個已經重複多次了。。。。。。。。。再js裡已經重複了一次

淺拷貝,隻單單拷貝本身,不拷貝引用。

深拷貝,完整的遞歸拷貝。

修改後的代碼

public class Mail implements Cloneable {    // 繼承自java本身就有的空接口,即Cloneable
    // 收件人
    private String receiver;
    // 郵件名稱
    private String subject;
    // 稱謂
    private String appellation;
    // 郵件内容
    private String contxt;
    // 郵件尾部
    private String tail;
    // 構造函數
    public Mail(AdvTemplate advTemplate){
        this.contxt = advTemplate.getAdvContext();
        this.subject = advTemplat.getAdvSubject()
    }
    // 下面進行淺拷貝,重寫clone方法
    @Override
    public Mail clone(){
        Mail mail = null;
        try{
            mail = (Mail)super.clone();
        }catch(CloneNotSupportedException e){
            e.printStackTrace();
        }
        return mail;
    }
    // get set方法
    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 getApplation(){
        return applation;
    }
    public void setApplation(String applation){
        this.appellation = applation
    }
    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("  ");
        while(i < MAX_COUNT){
            Mail cloneMail = mail.clone();
            cloneMail.setAppllation(getRandString(5) + "先生(女士)");
            cloneMail.setReceiver(getRandString(5) + "@" + mail.getRandString() + ".com");
            // 發送郵件
            sendMail(cloneMail );
            i++;
        }
    }
    // 發送郵件
    public static void sendMail(Mail mail){
        System.out.println("标題" + mail.getSubject() + "發送成功");
    }
    // 擷取指定長度的随機字元串
    public static String getRandString(int maxLength){
        String source = "abcdefghijklmnopqrstuvwxyz";
        // 緩沖區
        StringBuffer sb = new StringBuffer();
        // 随機數
        Random rand = new Random();
        // 進行循環
        for(int i = 0; i < maxLength; i++){
            // 進行随機取字元數
            sb.append(source.charAt(rand.nextlnt(source.length())));    // rand.nextInt()    生成僞随機數,放入到緩沖區内
        }
        return sb.toString();    // 傳回生成的僞字元串
    }
}           

使用拷貝,将sendMail放入線程池裡,每次拷貝一個對象,然後将對象放入sendMail,然後将sendMail放入線程裡,每次運作一個線程,拷貝一個對象,這樣解決,一個線程還未發送完成郵件的時候,就傳入的對象被修改的問題。

最後 深拷貝

實作深拷貝

在clone内部,将該對象引用的對象,再次進行拷貝即可。

應用

打飛機遊戲中,主飛機,使用單例模式,其餘飛機,使用原型模式,以一架飛機為原型,生成多個飛機。後者使用深拷貝。