1. 程式人生 > >設計模式-原型模式(06)

設計模式-原型模式(06)

項目 http shm 實現 正文 ets p s spec 優化

定義

  原型(Prototype Pattern)是一個簡單的設計模式。原型模式的英文原話是:Specify the kind of objects to create using a prototypical instance,and create new objects by copying this prototype.意思是:用原型實例指定創建對象的種類,並且通過復制這些原型創建新的對象。

  原型模式有三種角色:

  1.客戶(Client)角色:該角色提出創建對象的請求。
  2.抽象原型(Prototype):該角色是一個抽象角色,通常由一個java接口或抽象類實現,給出所有的具體原型類所需要的接口。

  3.具體原型(Concrete Prototype)角色:該角色是被復制的對象,必須實現抽象原型接口。

java中內置了克隆機制。object類具有一個clone()方法,能夠實現對對象的克隆,是一個類支持克隆只需要兩步:

  1.實現Cloneable接口。
  2.覆蓋Object的clone()方法,完成對象的克隆操作,通常只需要調用Object的clone()方法即可。為了使外部能夠調用此類的clone()方法,可以將訪問修飾符改為public。

/**
 * 抽象原型角色(Prototype)
 * 給出具體原型類復制所需要的接口
 */
public interface
Prototype { //克隆方法 Prototype clone(); } /** * 具體原型工廠類 * */ public class ConcretePrototype implements Prototype { @Override public Prototype clone() { try { return (Prototype)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace();
return null; } } } public class Client { public void operation(Prototype example) { //得到example Prototype prototype = example.clone(); } }

原型模式的優點

  1.性能優良:原型模式是對內存中二進制流的拷貝,要比直接new一個對象性能好,特別是當一個循環體內產生大量的對象時,原型模式可以更好地體現其優點。

  2.逃避構造函數的約束。這既是優點也是缺點,直接在內存中拷貝對象,構造函數是不會執行的,因此減少了約束,不過這一點需要在實際應用時進行權衡考慮。

原型模式的使用場景

  1.資源優化場景,類初始化時需要消化非常多的資源,這個資源包括數據、硬件資源等。

  2.性能和安全要求的場景,如果通過new產生一個對象需要非常繁瑣的數據準備和訪問權限,則可以使用原型模式。

  3.一個對象多個修改者的場景,一個對象需要提供給其他對象訪問,而且各個調用者可能都需要修改其值,可以考慮使用原型模式拷貝多個對象供調用者使用。

在實際項目中,原型模式很少單獨出現,一般是和工廠方法模式一起出現。原型模式通過clone()方法創建一個對象,然後由工廠方法提供給調用者。

例子

/**
 * 實現clone接口,實現了clone方法,是實現克隆的關鍵
 */
public class Mail implements Cloneable {
    //收件人
    private String receiver;
    //郵件標題
    private String subject;
    //稱謂
    private String appellation;
    //郵件內容
    private String contxt;
    //尾部
    private String tail;
    //構造函數
    public Mail(String subject,String contxt) {
        this.subject = subject;
        this.contxt = contxt;
    }
    //克隆方法
    public Mail clone() {
        Mail mail = null;
        try {
            mail=(Mail) super.clone();
            System.out.println(super.toString());   //super指的是被調用的那個對象
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return mail;
    }
}

/**
 * 調用
 */
public class SendMailDemo {
    Map students = new LinkedHashMap();
    public static void main(String[] args) {
        //創建一個原型mail
        Mail mail = new Mail("郵件標題", "郵件內容");
        mail.setTail("2017-11-20");
        SendMailDemo sendMailDemo = new SendMailDemo();
        //獲取所有學生
        Map students=sendMailDemo.getStudent();
        for (Object name : students.keySet()) {
            //克隆郵件
            Mail cloneMail = mail.clone();
            cloneMail.setAppellation(name.toString());
            cloneMail.setReceiver(students.get(name).toString());
            sendMailDemo.sendMail(cloneMail);
        }
        
    }
    public Map getStudent(){
        students.put("studentone", "[email protected]");
        students.put("studenttwo", "[email protected]");
        students.put("studentthree", "[email protected]");
        students.put("studentfour", "[email protected]");
        students.put("studentfive", "[email protected]");
        students.put("studentsix", "[email protected]");
        students.put("studentseven", "[email protected]");
        return students;
    }
    public void sendMail(Mail mail){
        System.out.println("標題:"+mail.getSubject()+"\t收件人郵箱:"+mail.getReceiver()+"\t正文:"+mail.getAppellation()+mail.getContxt()+"\t...已發送");
    }
}

源碼

設計模式-原型模式(06)