探索设计模式:原型模式

设计模式之原型模式

    • [🧐1. 概念](#🧐1. 概念)
    • [🎯2. 原型模式的作用](#🎯2. 原型模式的作用)
    • [📦3. 实现](#📦3. 实现)
      • [1. 定义原型接口](#1. 定义原型接口)
      • [2. 定义具体的原型类](#2. 定义具体的原型类)
      • [3. 定义客户端](#3. 定义客户端)
      • [4. 结果](#4. 结果)
    • [📰 4. 应用场景](#📰 4. 应用场景)
    • [🔍5. 深拷贝和浅拷贝](#🔍5. 深拷贝和浅拷贝)

在面向对象编程中,设计模式是一种通用的解决方案,用于解决软件设计过程中常见的问题。原型模式(Prototype Pattern)作为创建型设计模式的一员,旨在通过复制现有对象来创建新对象,而非通过常规的构造函数。这种模式不仅简化了对象的创建过程,而且在特定情况下还能显著提升性能。

🧐1. 概念


原型模式允许客户端复制一个已存在的对象,而不是通过常规的构造器创建一个新的实例。这种方法的主要优点在于,如果对象的创建成本很高(例如,初始化过程复杂、需要从数据库加载大量数据等),那么通过复制现有对象的方式可以有效减少资源消耗,提高系统的整体性能。

  1. Prototype抽象原型类):它是声明克隆方法的接口,是所有具体原型类的公共父类,可以是抽象类也可以是接口,甚至还可以是具体实现类。
  2. ConcretePrototype具体原型类):它实现在抽象原型类中声明的克隆方法,在克隆方法中返回自己的一个克隆对象。
  3. Client客户端类 ):通过调用 clone() 方法来创建新的对象,并展示了原始对象与克隆对象之间的独立性。

🎯2. 原型模式的作用

  1. 简化对象创建:通过复制现有的对象,可以避免复杂的构造过程,尤其是当对象的初始化需要进行大量的计算或资源分配时。
  2. 提高性能:对于那些创建成本高得对象,使用原型模式可以显著减少内存消耗和处理时间。
  3. 增加系统灵活性:通过修改原型对象得属性,可以快速生成不同状态的新对象,这比通过继承来实现更加灵活。

📦3. 实现


实现原型模式的核心在于定义一个原型接口,该接口包含一个用于复制自身的克隆方法。在不同的编程语言中,实现方式可能会有所不同,但基本思路是一致的。

1. 定义原型接口


java 复制代码
public interface Prototype extends Cloneable {
    Prototype clone();
}

此处的 Cloneable 接口是一个标记接口,表示该类可以被克隆。

类似的标记接口还有

  • Serializable:用于标记一个类的对象可以被序列化和反序列化。
  • RandomAccess:用于标记一个列表支持随机访问,即通过索引直接访问元素吗,而不是遍历。
  • Remote:用于远程方法调用,标记一个类支持远程方法调用。

2. 定义具体的原型类


java 复制代码
public class ConcretePrototype implements Prototype {

    private String attribute;

    public ConcretePrototype(String attribute) {
        this.attribute = attribute;
    }


    @Override
    public Prototype clone() {
        try {
            return (ConcretePrototype) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError("Cannot clone.", e);
        }
    }

    public String getAttribute() {
        return attribute;
    }

    public void setAttribute(String attribute) {
        this.attribute = attribute;
    }

}

3. 定义客户端


java 复制代码
public class Client {

    public static void main(String[] args) {
        ConcretePrototype prototype = new ConcretePrototype("Initial Value");
        ConcretePrototype clonedPrototype = (ConcretePrototype) prototype.clone();
        System.out.println("Original Attribute: " + prototype.getAttribute());
        System.out.println("Cloned Attribute: " + clonedPrototype.getAttribute());

        clonedPrototype.setAttribute("Modified Value");
        System.out.println("After Modification:");
        System.out.println("Original Attribute: " + prototype.getAttribute());
        System.out.println("Cloned Attribute: " + clonedPrototype.getAttribute());
    }
}

4. 结果


在这个示例中,ConcretePrototype 类实现了 Prototype 接口,并提供了具体的 clone() 方法实现。客户端代码展示了如何通过调用 clone() 方法来创建新的对象,并展示了原始对象与克隆对象之间的独立性。

📰 4. 应用场景


  1. 对象创建成本高:当对象的创建对象过程非常复杂或耗时,例如需要从网络加载数据、执行复炸的算法等,使用原型模式可以通过复制现有对象来节省时间和资源。
  2. 避免复杂的构造过程:如果对象的创建涉及到复杂的初始化步骤,使用原型模式可以简化这些步骤,通过复制已有对象来快速生成新的对象。
  3. 动态对象创建:在某些情况下,程序需要根据用户的输入或其他条件动态地创建对象。原型模式提供了一种灵活的方式来满足这种需求,无需预先定义所有的对象类型。
  4. 实际项目当中使用原型模式,实现 Cloneable 接口并重写 clone() 方法。或者编写自己的特有的原型类 Prototype ,然后实现 Prototypeclone() 方法。

🔍5. 深拷贝和浅拷贝


在讨论原型模式时,深拷贝浅拷贝 是一个不可忽视的话题。浅拷贝 只会复制对象的基本数据类型和其他对象的引用,而不会递归地复制引用对象本身。相反,深拷贝会递归地复制整个对象树,确保新对象与原有对象完全独立。

Java 中, 默认的 clone() 方法实现的是浅拷贝。如果需要实现深拷贝,通常需要手动编写代码来处理对象中的引用类型属性。例如,可以使用序列化和反序列化的方式来实现深拷贝:

java 复制代码
public class DeepClonePrototype implements Cloneable, Serializable {

    private transient String attribute; // 使用 transient 修饰符表示不参与序列化

    public DeepClonePrototype(String attribute) {
        this.attribute = attribute;
    }
    
    public String getAttribute() {
        return this.attribute;
    }
    
    public void setAttribute(String attribute) {
        this.attribute = attribute;
    }

    @Override
    protected DeepClonePrototype clone() {
        try {
            // 使用序列化和反序列化实现深拷贝
            ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(byteOut);
            out.writeObject(this);

            ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
            ObjectInputStream in = new ObjectInputStream(byteIn);
            return (DeepClonePrototype) in.readObject();
        } catch (IOException | ClassNotFoundException e) {
            throw new AssertionError("Cannot clone.", e);
        }
    }

}
相关推荐
思忖小下7 小时前
梳理你的思路(从OOP到架构设计)_简介设计模式
设计模式·架构·eit
liyinuo20179 小时前
嵌入式(单片机方向)面试题总结
嵌入式硬件·设计模式·面试·设计规范
aaasssdddd9611 小时前
C++的封装(十四):《设计模式》这本书
数据结构·c++·设计模式
T1an-112 小时前
设计模式之【观察者模式】
观察者模式·设计模式
思忖小下13 小时前
梳理你的思路(从OOP到架构设计)_设计模式Factory Method模式
设计模式·工厂方法模式·eit
霁月风14 小时前
设计模式——工厂方法模式
c++·设计模式·工厂方法模式
发飙的蜗牛'16 小时前
23种设计模式
android·java·设计模式
NorthCastle1 天前
设计模式-创建型模式-简单工厂模式详解
设计模式·简单工厂模式
越甲八千1 天前
重拾设计模式-外观模式和适配器模式的异同
设计模式·适配器模式·外观模式
越甲八千1 天前
重拾设计模式--适配器模式
设计模式·适配器模式