編輯:關於Android編程
用原型實例指定創建對象的種類,並通過拷貝這些原型創建新的對象。
1、類初始化需要消化非常多的資源,這個資源包括數據、硬件資源等,通過原型拷貝避免這些消耗;
2、通過 new 產生一個對象需要非常繁瑣的數據准備或訪問權限,則可以使用原型模式;
3、一個對象需要提供給其他對象訪問,而且各個調用者可能都需要修改其值時,可以考慮使用原型模式拷貝多個對象供調用者使用,即保護性拷貝。
Client : 客戶端用戶。
Prototype : 抽象類或者接口,聲明具備clone能力。
ConcretePrototype : 具體的原型類.
下面我們以簡單的文檔拷貝為例來演示一下簡單的原型模式模式。
package com.dp.example.builder;
package com.dp.example.prototype;
import java.util.ArrayList;
import java.util.List;
/**
* 文檔類型, 扮演的是ConcretePrototype角色,而cloneable是代表prototype角色
*
* @author mrsimple
*/
public class WordDocument implements Cloneable {
/**
* 文本
*/
private String mText;
/**
* 圖片名列表
*/
private ArrayList mImages = new ArrayList();
public WordDocument() {
System.out.println("----------- WordDocument構造函數 -----------");
}
/**
* 克隆對象
*/
@Override
protected WordDocument clone() {
try {
WordDocument doc = (WordDocument) super.clone();
doc.mText = this.mText;
doc.mImages = this.mImages;
return doc;
} catch (Exception e) {
}
return null;
}
public String getText() {
return mText;
}
public void setText(String mText) {
this.mText = mText;
}
public List getImages() {
return mImages;
}
/**
* @param img
*/
public void addImage(String img) {
this.mImages.add(img);
}
/**
* 打印文檔內容
*/
public void showDocument() {
System.out.println("----------- Word Content Start -----------");
System.out.println("Text : " + mText);
System.out.println("Images List: ");
for (String imgName : mImages) {
System.out.println("image name : " + imgName);
}
System.out.println("----------- Word Content End -----------");
}
}
通過WordDocument類模擬了word文檔中的基本元素,即文字和圖片。WordDocument的在該原型模式示例中扮演的角色為ConcretePrototype, 而Cloneable的角色則為Prototype。WordDocument實現了clone方法以實現對象克隆。下面我們看看Client端的使用 :
public class Client {
public static void main(String[] args) {
WordDocument originDoc = new WordDocument();
originDoc.setText("這是一篇文檔");
originDoc.addImage("圖片1");
originDoc.addImage("圖片2");
originDoc.addImage("圖片3");
originDoc.showDocument();
WordDocument doc2 = originDoc.clone();
doc2.showDocument();
doc2.setText("這是修改過的Doc2文本");
doc2.showDocument();
originDoc.showDocument();
}
}輸出結果如下 :
可以看到,doc2是通過originDoc.clone()創建的,並且doc2第一次輸出的時候和originDoc輸出是一樣的。即doc2是originDoc的一份拷貝,他們的內容是一樣的,而doc2修改了文本內容以後並不會影響originDoc的文本內容。需要注意的是通過clone拷貝對象的時候並不會執行構造函數!
將main函數的內容修改為如下 :
public static void main(String[] args) {
WordDocument originDoc = new WordDocument();
originDoc.setText("這是一篇文檔");
originDoc.addImage("圖片1");
originDoc.addImage("圖片2");
originDoc.addImage("圖片3");
originDoc.showDocument();
WordDocument doc2 = originDoc.clone();
doc2.showDocument();
doc2.setText("這是修改過的Doc2文本");
doc2.addImage("哈哈.jpg");
doc2.showDocument();
originDoc.showDocument();
}細心的朋友可能發現了,在doc2添加了一張名為"哈哈.jpg"的照片,但是卻也顯示在originDoc中?這是怎麼回事呢? 其實學習過C++的朋友都知道,這是因為上文中WordDocument的clone方法中只是簡單的進行淺拷貝,引用類型的新對象doc2的mImages只是單純的指向了this.mImages引用,而並沒有進行拷貝。doc2的mImages添加了新的圖片,實際上也就是往originDoc裡添加了新的圖片,所以originDoc裡面也有"哈哈.jpg" 。那如何解決這個問題呢? 那就是采用深拷貝,即在拷貝對象時,對於引用型的字段也要采用拷貝的形式,而不是單純引用的形式。示例如下 :
/**
* 克隆對象
*/
@Override
protected WordDocument clone() {
try {
WordDocument doc = (WordDocument) super.clone();
doc.mText = this.mText;
// doc.mImages = this.mImages;
doc.mImages = (ArrayList) this.mImages.clone();
return doc;
} catch (Exception e) {
}
return null;
} 如上代碼所示,將doc.mImages指向this.mImages的一份拷貝, 而不是this.mImages本身,這樣在doc2添加圖片時並不會影響originDoc,如圖所示 :在Android源碼中,我們以熟悉的Intent來分析源碼中的原型模式。簡單示例如下 :
Uri uri = Uri.parse("smsto:0800000123");
Intent shareIntent = new Intent(Intent.ACTION_SENDTO, uri);
shareIntent.putExtra("sms_body", "The SMS text");
Intent intent = (Intent)shareIntent.clone() ;
startActivity(intent);結果如下 :
可以看到,我們通過shareIntent.clone方法拷貝了一個對象intent, 然後執行startActivity(intent), 隨即就進入了短信頁面,號碼為0800000123,文本內容為The SMS text,即這些內容都與shareIntent一致。
下面我們看看Intent的clone的實現 :
@Override
public Object clone() {
return new Intent(this);
}
/**
* Copy constructor.
*/
public Intent(Intent o) {
this.mAction = o.mAction;
this.mData = o.mData;
this.mType = o.mType;
this.mPackage = o.mPackage;
this.mComponent = o.mComponent;
this.mFlags = o.mFlags;
if (o.mCategories != null) {
this.mCategories = new ArraySet(o.mCategories);
}
if (o.mExtras != null) {
this.mExtras = new Bundle(o.mExtras);
}
if (o.mSourceBounds != null) {
this.mSourceBounds = new Rect(o.mSourceBounds);
}
if (o.mSelector != null) {
this.mSelector = new Intent(o.mSelector);
}
if (o.mClipData != null) {
this.mClipData = new ClipData(o.mClipData);
}
} 可以看到,clone方法實際上在內部調用了new Intent(this); 這就和C++中的拷貝構造函數完全一致了,而且是深拷貝。由於該模式比較簡單,就不做太多說明。
全景視頻拼接(二)--OpenCV源碼解析
一、stitching_detail程序運行流程1.命令行調用程序,輸入源圖像以及程序的參數2.特征點檢測,判斷是使用surf還是orb,默認是surf。3.對圖像的特征
Android屬性動畫
屬性動畫屬性動畫的核心主要是ObjectAnimator,ValueAnimator這幾個對象的使用。下面對各個方法的使用進行介紹。ObjectAnimator的使用:一
Android RecyclerView實現下拉列表功能
現在市面上的很多的應用,都帶有下拉列表的功能,將所有選項都放在下拉列表中,當用戶點擊選擇的時候,彈出所有的選項,用戶選擇一項後,下拉列表自動隱藏,很多下拉列表都是用Lis
一、初識GVR ---- Android VR視頻/Google VR for Android /VR Pano/VR Video
業余時間充足,於是想弄點自己的東西,找來找去還是回到當初感興趣的VR。目前好像沒有太多關於VR方面的教程,於是有了寫‘學習筆記’的想法。說干就干~