原型设计模式
程序员文章站
2024-03-17 17:36:52
...
定义
用原型模式指定创建对象的种类,并通过复制这些原型创建新的对象。
原型设计模式,是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 ————————
深浅拷贝问题
注意对于非基本数据类型的引用类型的浅拷贝问题,由于指向的同一堆对象内存地址,修改一处后多处引用会存在联动问题。
一般建议原型模式尽量使用深拷贝,避免对原型对象造成副作用。