Android设计模式1--原型模式
1. 定义
原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
2. 使用场景
- 资源优化场景:类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
- 性能和安全要求的场景:通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
- 一个对象多个修改者的场景:一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
3. 实现
3.1 基类需要实现Cloneable接口:
/**
* Created by LJW on 2019/3/12.
* 原型模式
* 原型模式也是拷贝模式,就是在内存中拷贝原型对象来创建一个跟原型对象一模一样的新对象。
* 原型模式的实质就是扩展使用clone方法。
*/
public class WordDocument implements Cloneable {
public WordDocument(){}
private String mText;
private ArrayList<String> mIcon = new ArrayList<>();
@Override
protected WordDocument clone() throws CloneNotSupportedException {
WordDocument wordDocument = (WordDocument) super.clone();
wordDocument.mText = this.mText;
wordDocument.mIcon = this.mIcon;
return wordDocument;
}
public String getmText() {
return mText;
}
public void setmText(String mText) {
this.mText = mText;
}
public ArrayList<String> getmIcon() {
return mIcon;
}
public void addIcon(String icon){
this.mIcon.add(icon);
}
public void showDocument() {
System.out.println("----------- Word Content Start -----------");
System.out.println("Text : " + mText);
System.out.println("Images List: ");
for (String imgName : mIcon) {
System.out.println("image name : " + imgName);
}
System.out.println("----------- Word Content End -----------");
}
}
3.2 测试代码:
/**
* Created by LJW on 2019/3/12.
*/
public class ClientTest {
public static void main(String[] args) {
WordDocument origDocument = new WordDocument();
origDocument.setmText("第一篇文档");
origDocument.addIcon("图片一");
origDocument.addIcon("图片二");
origDocument.addIcon("图片三");
origDocument.showDocument();
try {
WordDocument clone = origDocument.clone();
clone.setmText("我修改了内容");
clone.showDocument();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
origDocument.showDocument();
}
}
3.3 执行结果:
----------- Word Content Start -----------
Text : 第一篇文档
Images List:
image name : 图片一
image name : 图片二
image name : 图片三
----------- Word Content End -----------
----------- Word Content Start -----------
Text : 我修改了内容
Images List:
image name : 图片一
image name : 图片二
image name : 图片三
----------- Word Content End -----------
----------- Word Content Start -----------
Text : 第一篇文档
Images List:
image name : 图片一
image name : 图片二
image name : 图片三
----------- Word Content End -----------
4. 浅拷贝和深拷贝
4.1 浅克隆
上述原型模式的实现实际上只是一个浅拷贝,也称为影子拷贝。这种拷贝并不是将原始文档的所有字段都重新构造一份,而是副本文档的字段引用原始文档的字段。如下图所示:
4.2 深克隆
所谓深克隆,就是把上面的文档的所有字段都重新构造一份,副本文档的字段不再引用原始文档的字段。如下图所示:
修改代码如下:
@Override
protected WordDocument clone() throws CloneNotSupportedException {
WordDocument wordDocument = (WordDocument) super.clone();
wordDocument.mText = this.mText;
wordDocument.mIcon = (ArrayList<String>) this.mIcon.clone();
return wordDocument;
}
5. 优点
- 性能优良:原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体内产生大量的对象时,原型模式可以更好地体现其优点。
6. 缺点
- 逃避构造函数的约束(clone的时候,构造函数不会执行):这既是它的优点也是缺点,直接在内存中拷贝,构造函数是不会执行的,需要在实际应用时考虑。
- 需要注意类中可变引用成员浅拷贝带来的问题,可以考虑使用深拷贝(对成员也进行一次clone,并且赋值给新对象的成员)
- 类成员中有final类型的成员,这个类不能进行clone。(此时应该去掉final关键字)