設計模式(6)----原型模式
- 簡介:
- Prototype原型模式是一種創建型設計模式,Prototype模式允許一個對象再創建另外一個可定制的對象,根本無需知道任何如何創建的細節,工作原理是:通過將一個原型對象傳給那個要發動創建的對象,這個要發動創建的對象通過請求原型對象拷貝它們自己來實施創建。
- 定義:
- 用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。
- 組成:
- 客戶(Client)客戶端,讓原型對象克隆自身創建新對象
- 抽象原型類:聲明克隆方法的接口,是所有具體原型類的公共父類,它可以是抽象類也可以是接口
- 具體原型類:它實現抽象原型類中聲明的克隆方法,在克隆方法中返回自己的一個克隆對象
- 步驟:
- 定義一個消息模板類,用來統一通知消息的模板
- 定義一個消息模板類,用來統一通知消息的模板
package com.lvsling.prototype;
/** * 活動通知模板 * @author Administrator * */ public class AdvTemplate {
private String advSubject = "超市抽獎活動"; private String advContext = "超市國慶抽獎活動通知:只要購物就送獎勵"; public String getAdvSubject() { return advSubject; } public void setAdvSubject(String advSubject) { this.advSubject = advSubject; } public String getAdvContext() { return advContext; } public void setAdvContext(String advContext) { this.advContext = advContext; }
} |
- 定義一個Mial類,也就是具體原型類,實現Cloneable(這裏代表抽象原型類)接口
package com.lvsling.prototype;
public class Mail implements Cloneable{
private String receiver; private String sbuject; private String appelation; private String contxt; private String tail;
public Mail(AdvTemplate advTemplate) { this.contxt = advTemplate.getAdvContext(); }
@Override protected Mail clone() throws CloneNotSupportedException { Mail mail = null; //使用此方法來獲取對象引用 mail = (Mail) super.clone(); return mail; }
public String getReceiver() { return receiver; }
public void setReceiver(String receiver) { this.receiver = receiver; }
public String getSbuject() { return sbuject; }
public void setSbuject(String sbuject) { this.sbuject = sbuject; }
public String getAppelation() { return appelation; }
public void setAppelation(String appelation) { this.appelation = appelation; }
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; }
} |
- 定義一個Client客戶端,讓原型對象克隆而創建一個新對象。
package com.lvsling.prototype;
public class ClientMain {
public static void main(String[] args) throws CloneNotSupportedException { Mail mail = new Mail(new AdvTemplate()); mail.setTail("華聯超市"); Mail cloneMail = mail.clone(); cloneMail.setAppelation("張先生"); sendMail(cloneMail); }
public static void sendMail(Mail mail) { System.out.println("超市:"+mail.getTail()); System.out.println("收件人:"+mail.getAppelation()); System.out.println("標題:"+mail.getContxt()); } } |
- 控制臺打印結果為:
超市:華聯超市 收件人:張先生 標題:超市國慶抽獎活動通知:只要購物就送獎勵 |
- 優點:
- 當創建對象的實例較為復雜的時候,使用原型模式可以簡化對象的創建過程,通過復制一個已有的實例可以提高實例的創建效率。
- 擴展性好,由於原型模式提供了抽象原型類,在客戶端針對抽象原型類進行編程,而將具體原型類寫到配置文件中,增減或減少產品對原有系統都沒有影響。
- 原型模式提供了簡化的創建結構,工廠方法模式常常需要有一個與產品類等級結構相同的工廠等級結構,而原型模式不需要這樣,圓形模式中產品的復制是通過封裝在類中的克隆方法實現的,無需專門的工廠類來創建產品。
- 可以使用深克隆方式保存對象的狀態,使用原型模式將對象復制一份並將其狀態保存起來,以便在需要的時候使用(例如恢復到歷史某一狀態),可輔助實現撤銷操作。
- 缺點:
- 需要為每一個類配置一個克隆方法,而且該克隆方法位於類的內部,當對已有類進行改造的時候,需要修改代碼,違反了開閉原則。
- 在實現深克隆時需要編寫較為復雜的代碼,而且當對象之間存在多重簽到引用時,為了實現深克隆,每一層對象對應的類都必須支持深克隆,實現起來會比較麻煩。
- 應用場景:
- 創建新對象成本較大(例如初始化時間長,占用CPU多或占太多網絡資源),新對象可以通過復制已有對象來獲得,如果相似對象,則可以對其成員變量稍作修改。
- 系統要保存對象的狀態,而對象的狀態很小。
- 需要避免使用分層次的工廠類來創建分層次的對象,並且類的實例對象只有一個或很少的組合狀態,通過復制原型對象得到新實例可以比使用構造函數創建一個新實例更加方便。
- 總結:
- 以上是原型模式的理解,原型模式通過Object的clone()方法來實現的,是內存操作,無視構造方法和訪問權限,直接獲取新的對象。在了解一下深拷貝和淺拷貝就OK了
設計模式(6)----原型模式