1. 模式简介
原型实例指定创建对象的种类,通过克隆
这些原型创建新的对象。调用者不需要指定对象的创建细节,不通过调用构造函数创建对象。属于创建型设计模式
。
2. 示例代码
2.1. 浅克隆
2.1.1. 代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
public interface Money {
Money print(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
@Getter @Setter @NoArgsConstructor @AllArgsConstructor public class Shape implements Serializable {
private String desc; }
@Getter @Setter public class HundredMoney implements Money { private Shape shape;
@Override public Money print() { HundredMoney hundredMoney = new HundredMoney(); hundredMoney.setShape(this.shape); return hundredMoney; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
public class PatternTest { public static void main(String[] args) { HundredMoney money1 = new HundredMoney(); money1.setShape(new Shape("纸币"));
HundredMoney money2 = (HundredMoney) money1.print();
System.out.println("money1 -> 引用对象地址:" + money1.getShape()); System.out.println("money2 -> 引用对象地址:" + money2.getShape()); System.out.println("引用对象地址比较:" + (money1.getShape() == money2.getShape())); } }
|
1 2 3
| money1 -> 引用对象地址:com.xkcoding.design.pattern.creational.prototype.Shape@1d44bcfa money2 -> 引用对象地址:com.xkcoding.design.pattern.creational.prototype.Shape@1d44bcfa 引用对象地址比较:true
|
2.1.2. UML图例

2.2. 深克隆
深克隆一定需要实现 Serializable
接口
2.2.1. 代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
public interface Money {
Money print(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
@Getter @Setter @NoArgsConstructor @AllArgsConstructor public class Shape implements Serializable {
private String desc; }
@Getter @Setter public class HundredMoney implements Money, Cloneable, Serializable { private Shape shape;
@Override public Money print() { return (Money) this.clone(); }
@Override protected Object clone() { return this.deepClone(); }
@SneakyThrows private Object deepClone() { @Cleanup ByteArrayOutputStream bos = new ByteArrayOutputStream(); @Cleanup ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this);
@Cleanup ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); @Cleanup ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject(); }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
public class PatternTest { public static void main(String[] args) { HundredMoney money1 = new HundredMoney(); money1.setShape(new Shape("纸币"));
HundredMoney money2 = (HundredMoney) money1.print();
System.out.println("money1 -> 引用对象地址:" + money1.getShape()); System.out.println("money2 -> 引用对象地址:" + money2.getShape()); System.out.println("引用对象地址比较:" + (money1.getShape() == money2.getShape())); } }
|
1 2 3
| money1 -> 引用对象地址:com.xkcoding.design.pattern.creational.prototype.Shape@355da254 money2 -> 引用对象地址:com.xkcoding.design.pattern.creational.prototype.Shape@12edcd21 引用对象地址比较:false
|
2.2.2. UML图例

3. 应用
4. 场景
- 类初始化消耗资源较多
- 创建对象的时候步骤繁琐(数据准备、访问权限等初始化)
- 构造函数复杂
- 循环体重创建大量对象
6. 优缺点
优点: 原型模式性能比直接new一个对象性能高;简化了创建过程
缺点: 必须配备克隆(或者可拷贝)方法;对克隆复杂对象或者对克隆出的对象进行复杂改造时,容易带来风险;浅克隆
和 深克隆
要运用得当
7. 完整代码地址
https://github.com/xkcoding/design-pattern/tree/master/src/main/java/com/xkcoding/design/pattern/creational/prototype