Android设计模式-原型模式

来源:互联网 发布:linux 删除oracle 编辑:程序博客网 时间:2024/05/21 10:57

原型模式定义:

用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

使用场景:

1. 类初始化需要消化非常多的资源,这个资源包括数据,硬件资源等,通过原型拷贝避免这些消耗。

2. 通过new产生一个对象需要非常繁琐的数据准备或者访问权限,这是可以使用·1原型模式

3. 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。


UML类图如下:


package com.yf.pattern.prototype;

import java.util.ArrayList;

/**
File: WordDocument.java
Description: TODO
@author 
@date 2016年12月28日 上午9:45:01
@version 1.0 
**/

/**
 * 
 * WordDocument,即ConcretePrototype的角色
 * Clonealbe代表Prototype角色
 */
public class WordDocument implements Cloneable{

private String mText;
private ArrayList<String> mImages = new ArrayList<String>();

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){
e.printStackTrace();
}
return null;
}

public String getmText() {
return mText;
}
public void setmText(String mText) {
this.mText = mText;
}
public ArrayList<String> getmImages() {
return mImages;
}
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 name: mImages){
System.out.println("Image name: " + name);
}
System.out.println("------ Word Content End ------");
}

}

运行结果如下:

------WordDocument构造函数------
------ Word Content Start ------
Text: 这是一篇文档
Images List: 
Image name: 图片1
Image name: 图片2
Image name: 图片3
------ Word Content End ------
------ Word Content Start ------
Text: 这是一篇文档
Images List: 
Image name: 图片1
Image name: 图片2
Image name: 图片3
------ Word Content End ------
------ Word Content Start ------
Text: 这是一个修改过的Doc2文本
Images List: 
Image name: 图片1
Image name: 图片2
Image name: 图片3
------ Word Content End ------
------ Word Content Start ------
Text: 这是一篇文档
Images List: 
Image name: 图片1
Image name: 图片2
Image name: 图片3
------ Word Content End ------


上述运行结果表明,clone拷贝对象的时候,不会运行构造函数。


浅拷贝和深拷贝

对于引用对象,如果仅仅使用

doc.mImages = this.mImages;

则属于浅拷贝;

那样上例中,如果修改doc2的引用对象,例如doc2.addImage()会同时修改doc2和originDoc这2个对象,因为doc2和originDoc都指向同一个引用对象。

如果在拷贝对象时,对于引用型的字段也采用拷贝的形式,则属于深拷贝,例如

doc.mImages = (ArrayList<String>)this.mImages.clone();

这样修改doc2,就完全不会影响originDoc

结论:在使用过程中尽量使用深拷贝,避免出现操作副本影响原始对象的问题。


clone方法可以用super.clone,也可以用new,两者区别在于:

根据构造对象的成本来决定,如果构造对象的成本比较高或者构造较为麻烦,则使用clone函数效率较高,否则可以使用new的形式




0 0