定义
用原型模式指定创建对象的种类,并通过复制这些原型创建新的对象。
原型设计模式,是23种设计模式的创建型模式,简单来说,就是对象的克隆。将要被克隆的对象,我们称之为原型。
使用场景
- 类初始化或new一个新对象,需要消耗非常多的资源的情况时,可以考虑使用原型设计模式提升对象创建的效率。——因为通过原型复制的方式不会执行构造方法,避免了初始化占有的时间和空间。
- 一个对象需要提供给其他对象访问,并且该对象希望对外是只读的情况时,可以考虑使用原型模式通过返回一个对象拷贝的形式实现只读的限制。——保护性拷贝。
UML类图
- Client:客户端角色。
- Prototype:抽象类或接口,声明具备clone能力。
- ConcretePrototype:具体的原型类。
代码实现
package com.tcl.tvweishi.middleware;
import java.util.ArrayList;
import java.util.Arrays;
/**
* 原型模式代码实现
* <p>
* WordDocument就是ConcretePrototype,Cloneable就是Prototype
*
* @author Agg
* @date 2020/06/29
*/
public class WordDocument implements Cloneable {
private String mText; // 模拟Word文档中的文字
private ArrayList<String> mImages = new ArrayList<>(); // 模拟Word文档中的图片
public WordDocument() {
System.out.println("constructed function");
}
public String getText() {
return mText;
}
public void setText(String mText) {
this.mText = mText;
}
public ArrayList<String> getImages() {
return mImages;
}
public void setImages(ArrayList<String> mImages) {
this.mImages = mImages;
}
public void showDocument() {
System.out.println("———————— Start ————————");
System.out.println("text = " + mText);
for (String image : mImages) {
System.out.println("image = " + image);
}
System.out.println("———————— End ————————");
}
@Override
protected WordDocument clone() {
try {
WordDocument wordDocument = (WordDocument) super.clone();
wordDocument.mText = this.mText;
// wordDocument.mImages = this.mImages; // 浅拷贝
wordDocument.mImages = (ArrayList<String>) this.mImages.clone(); // 深拷贝
return wordDocument;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static class Client {
public static void main(String[] args) {
// 构造原型
WordDocument wordDocument = new WordDocument();
wordDocument.setText("Hello World!");
wordDocument.setImages(new ArrayList(Arrays.asList("image1","image2","image3")));
// 原型+打印
wordDocument.showDocument();
// 拷贝+打印
WordDocument copyWordDocument = wordDocument.clone(); // 不会调用构造函数
copyWordDocument.showDocument();
// 修改+打印
copyWordDocument.setText("Hello Gold!");
copyWordDocument.setImages(new ArrayList(Arrays.asList("image4","image5","image6")));
copyWordDocument.showDocument();
// 原型+打印
wordDocument.showDocument();
}
}
}
打印:
constructed function
———————— Start ————————
text = Hello World!
image = image1
image = image2
image = image3
———————— End ————————
———————— Start ————————
text = Hello World!
image = image1
image = image2
image = image3
———————— End ————————
———————— Start ————————
text = Hello Gold!
image = image4
image = image5
image = image6
———————— End ————————
———————— Start ————————
text = Hello World!
image = image1
image = image2
image = image3
———————— End ————————
总结
总的来说原型设计模式在Android中的实现,可以通过clone也可以通过new新对象,需要通过构造对象的成本来选择。如果对象的构造成本比较高或者构造较为麻烦,那么使用clone函数效率较高,否则可以使用new形式。比如:Intent的clone()重写方式就是通过new Intent()去实现的。
- 深浅拷贝问题
注意对于非基本数据类型的引用类型的浅拷贝问题,由于指向的同一堆对象内存地址,修改一处后多处引用会存在联动问题。一般建议原型模式尽量使用深拷贝,避免对原型对象造成副作用。 - 优缺点
原型设计模式是在内存中二进制流的拷贝,要比直接new一个对象性能好很多。不过这既是它的优点亦是它的缺点,因为直接在内存中拷贝,构造函数不会执行,这是个需要注意的问题。