設計模式-原型模式
用原型執行個體指定建立對象的種類,通過拷貝這些原型建立新的對象。
電子賬單
即,使用電子賬單
// 廣告信模闆
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内部,将該對象引用的對象,再次進行拷貝即可。
應用
打飛機遊戲中,主飛機,使用單例模式,其餘飛機,使用原型模式,以一架飛機為原型,生成多個飛機。後者使用深拷貝。