5-原型模式

原型模式

image-20221123192538698

第一个对象的创建:

  • new创建
  • 工厂创建
  • 反射创建

第二个对象及之后的对象创建:

  • 克隆创建

    • 浅克隆
      • 引用对象的内存不复制
    • 深克隆
      • 引用对象的内存被复制
    • 浅克隆与深克隆都会创建全新的内存,新对象都会是独立的。

原型模式的定义

image-20221123193316513

对象创建型模式

  1. 工作原理:将一个原型对象传给要发动创建的对象(即客户端对象),这个要发动创建的对象通过请求原型对象复制自己来实现创建过程
  2. 创建新对象(也称为克隆对象)的工厂就是原型类自身工厂方法由负责复制原型对象的克隆方法来实现
  3. 通过克隆方法所创建的对象是全新的对象,它们在内存中拥有新的地址,每一个克隆对象都是独立的

原型模式结构

image-20221123193905923

clone()方法可能不同,所以由子类实现。

原型模式包含以下角色
  • Prototype(抽象原型类)

  • ConcretePrototype(具体原型类)

  • Client(客户类)

浅克隆与深克隆

  • 浅克隆(Shallow Clone):当原型对象被复制时,只复制它本身和其中包含的值类型的成员变量,而引用类型的成员变量并没有复制

    • image-20221123194306144
  • 深克隆(Deep Clone):除了对象本身被复制外,对象所包含的所有成员变量也将被复制

    • image-20221123194358754

java内置了浅克隆

通用的克隆实现方法

image-20221123194954934 image-20221123195016487
类Prototype与ConcretePrototype:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public interface Prototype {
public Prototype clone();
}

public class ConcretePrototype implements Prototype {
private String attr;

public void setAttr(String attr) {
this.attr = attr;
}

public String getAttr() {
return this.attr;
}

//克隆方法
public Prototype clone() {
ConcretePrototype prototype = new ConcretePrototype(); //创建新对象
prototype.setAttr(this.attr);
return prototype;
}
}
客户端Client:
1
2
3
4
5
……
ConcretePrototype prototype = new ConcretePrototype();
prototype.setAttr("Sunny");
ConcretePrototype copy = (ConcretePrototype)prototype.clone();
……
Java语言中的clone()方法和Cloneable接口
  • 在Java语言中,提供了一个clone()方法用于实现浅克隆,该方法使用起来很方便,直接调用super.clone()方法即可实现克隆

image-20221123200112603

需要将Object进行类型转换

1
2
3
//客户端代码操作
Prototype prototype = new ConcretePrototype();
Prototype copy = prototype.clone();
实例类图1:
image-20221123200500730
浅克隆的实现方案:
image-20221123200510033

浅克隆

工作周报对象被成功复制,但是附件对象并没有复制,实现了浅克隆;

附件Attachment类要先new创建之后再注入到WeeklyLog中。存在Attachment的对象attachment为WeeklyLog类的属性并且存在attachment的注入,所以是聚合关系

深克隆的实现方案:

工作周报类WeeklyLog和附件类Attachment实现==Serializable接口==

image-20221123201320535

通过序列化和反序列化的方式获得深克隆对象

(具体的代码参考书P100\textcolor{red}{(具体的代码参考书P100)}

深克隆

工作周报对象和附件对象都成功复制,实现了深克隆

节点流:操纵内存、硬盘等

过滤流:连接

输入流与输出流:以程序为参照物

  1. 程序输出到文件为输出流\longrightarrow写文件;

  2. 文件输入到程序为输入流\longrightarrow读文件;

原型管理器

原型管理器(Prototype Manager)将多个原型对象存储在一个集合中供客户端使用,它是一个专门负责克隆对象的工厂,其中定义了一个集合用于存储原型对象,如果需要某个原型对象的一个克隆,可以通过复制集合中对应的原型对象来获得。

原型管理器结构
image-20221123202928444
代码实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.*;

public class PrototypeManager {
private Hashtable prototypeTable=new Hashtable(); //使用Hashtable存储原型对象
public PrototypeManager() {
prototypeTable.put("A", new ConcretePrototypeA());
prototypeTable.put("B", new ConcretePrototypeB());
}

public void add(String key, Prototype prototype) {
prototypeTable.put(key,prototype);
}

public Prototype get(String key) {
Prototype clone = null;
clone = ((Prototype) prototypeTable.get(key)).clone(); //通过克隆方法创建新对象
return clone;
}
}

模式优点

  • 简化对象的创建过程,通过复制一个已有实例可以提高新实例的创建效率

  • 扩展性较好

    • 符合开闭原则
  • 提供了简单的创建结构,原型模式中产品的复制是通过封装在原型类中的克隆方法实现的,无须专门的工厂类来创建产品

    • 自己创建自己
  • 可以使用深克隆的方式保存对象的状态,以便在需要的时候使用,可辅助实现撤销操作

    • 实现ctrl+C、ctrl+Z操作

模式缺点

  • 需要为每一个类配备一个克隆方法,而且该克隆方法位于一个类的内部,当对已有的类进行改造时,需要修改源代码,违背了开闭原则

  • 实现深克隆时需要编写较为复杂的代码,而且当对象之间存在多重的嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆(每一层的对应的类都需要实现Serializable接口),实现起来可能会比较麻烦

模式适用环境

  • 创建新对象成本较大,新对象可以通过复制已有对象来获得,如果是相似对象,则可以对其成员变量稍作修改

  • 系统要保存对象的状态,而对象的状态变化很小

  • 需要避免使用分层次的工厂类来创建分层次的对象

  • Ctrl + C\longrightarrowCtrl + V

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2023-2024 Guijie Wang
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信