1. 程式人生 > >一次原型模式的模擬情況

一次原型模式的模擬情況

修飾 cli detail 應用場景 程序 人的 代碼 rec 對象

走穿java23種設計模式-5原型模式

原型模式很多人對這個設計模式也是不熟悉的。因為用得也是不多,原型模式一般用於多次創建一個類的對象,獲取多個這個類的對象,並進行相應的操作,一般做法是多次new出來,但是原型模式是復制第一次創建的對象,然後通過多次復制得到多個對象。這種需求可能在現實需求中比較少,但是了解多一點沒什麽錯。。。

原型模式的現實場景

比如要通知幾十個客戶有買車的實惠信息。
你不會笨到一個個客戶去給他單獨的寫郵件和郵件裏面的信息吧。
好一點的做法就是寫好一封郵件內容,發給第一個客戶。
如果內容發送正常,就上一次發送的郵件信息轉發或復制給剩下的幾十個客戶的郵箱裏面。
上面就是一次原型模式的模擬情況。

原型模式的定義

用原型實例指定創建對象的種類,並且通過復制這些原型創建新的對象。

原型模式的類圖

1

原型模式設計到三種角色

1.客戶角色

該角色提出創建對象的請求。

2.抽象原型角色

該角色是一個抽象角色,通常由一個java接口或抽象類實現,給出所有的具體原型類所需要的接口。

3.具體原型角色

該角色是被復制的對象,必須實現抽象原型接口。

原型模式的優點/缺點

1.性能優化

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

2.逃避構造函數的約束。

這既是優點,也是缺點,直接在內存中拷貝對象,構造函數是不會執行的,因此減少了約束,但是也有可能造成沒有對一些數據繼續必要的初始化,這一點要在實際應用中進行權衡考慮。

原型模式的應用場景

1.資源優化場景。

類初始化時需要消化非常多的資源,這個資源包括數據、硬件資源等等,原型模式就能跳過這些步驟。

2.性能和安全要求的場景。

如果通過new來產生一個對象需要非常繁瑣的數據準備和訪問權限,則可以通過原型模式。

3.一個對象多個修改者的場景。

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

java克隆對象

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

1.實現接口Cloneable類

2.覆蓋Object的clone()方法,完成對象的克隆操作,通常只需要調用Object的clone()方法即可。

為了使外部能夠調用此類的clone()方法,可以將訪問修飾符改為public。

原型設計模式的實例

這裏就以通知多個客戶的情況做示例。

原型模式實例類圖

1

各個接口/類的代碼

1.抽象原型角色接口:Cloneable

這是系統的接口類,直接實現它就可以了

2.具體原型角色:Email

package p5_prototype;


/**
* 繼承了Cloneable 接口的類
* 用於完成對象的復制
* 完成通過自身對象復制出一個新的對象
*/
public class Email implements Cloneable {
//郵件的基本信息
private String receiver;//郵件的接收人
private String title;//郵件標題
private String contxt;//郵件內容

/**
* 構造方法
*/
public Email(String title, String contxt) {//因為標題和內容一樣
this.title = title;
this.contxt = contxt;

}

/**
* 克隆方法
* 克隆對象的具體實現
* 覆蓋掉原本的clone方法
* 通過自身對象調用clone方法,可以得到新的對象
*/
public Email clone() {
Email email = null;
try {
email = (Email) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return email;

}


//get和set方法,不管是new出來的對象還是復制出來的對象都是可以調用下面的方法
public String getReceiver() {
return receiver;
}

public void setReceiver(String receiver) {
this.receiver = receiver;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getContxt() {
return contxt;
}

public void setContxt(String contxt) {
this.contxt = contxt;
3.客戶角色:BenzClient

package p5_prototype;

import java.util.ArrayList;
import java.util.List;

/**
* 原型的客戶,接手郵件
*/
public class BenzClient {

List<String> receiverList = new ArrayList<String>();//要發送的收件人的集合

/**
* 在集合中添加收件人
*/
public List<String> getEmeilList() {
receiverList.add("李先生");
receiverList.add("梁小姐");
receiverList.add("習先生");
receiverList.add("大飛機");
return receiverList;
}

/**
* 發送郵件的方法
* 模擬發送。。。
*/
public void sendEmail(Email email) {
System.out.println("發送郵件給:" + www.zhenloyl88.cn email.getReceiver() + ",標題:" + email.getTitle() + ",內容:" + email.getContxt());

我這裏是把客戶群體當成是一個對象。

4.原型模式的調用類:PrototypeDemo


package p5_prototype;

/**
* 原型模式的調用者,客戶
*/
public class PrototypeDemo {


public static void main(String[] srgs) {
//創建一個Email原型,用來被復制
Email email = new Email("買車優惠活動", "十一期間買車就送一個超級大娃娃");
BenzClient client = new BenzClient();//客戶對象,接收郵件
//給所有用戶發送郵件
int num = client.getEmeilList().size();//客戶的個數
for (int i = 0; i < num; i++) {
Email copyEmail = email.clone();//根據對象復制新的對象
String receiver = client.getEmeilList().get(i);//獲取集合中的收件人
copyEmail.setReceiver(receiver);//給郵件添加收件人

程序運行結果:

2

之前也詳細介紹過了java設計模式中的其他四種創建型模式:

建造者模式:http://blog.csdn.net/ www.7881188.cn wenzhi20102321/article/details/78163855

抽象工廠模式:http://blog.csdn.net/wenzhi20102321/article/details/78153437
工廠方法模式:http://www.lgzxyl.com /78129065
可以仔細對比一下工廠方法模式和抽象工廠模式,看看概念,看看類圖,看看代碼,就會明白了。

單例模式:http://blog.csdn.net/wenzhi20102321/article/details/77882203

java 23種設計模式介紹:http://www.wmyld11.cn

國慶假期馬上就要結束了。。。

共勉:爭取更加美好的未來。

一次原型模式的模擬情況