设计模式之 原型模式

原型模式是一种创建型设计模式,它通过复制现有的实例来创建新的对象,而不是通过传统的构造方法。通过这个模式,可以避免重复的初始化操作,尤其适用于当创建一个对象需要耗费较大资源或时间时。原型模式的核心思想是"通过克隆现有对象来创建新的对象",这样既能减少对象创建的开销,又能保证新对象的创建更加灵活。

1. 原型模式的定义

原型模式的定义为:使用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象 。具体来说,它的核心是通过实现一个 clone 方法,使得我们可以复制(克隆)对象的状态而无需重新构造。这个方法通常会返回对象的一个副本,而不是重新实例化一个新对象。

2. 原型模式的结构

原型模式通常由以下几个角色组成:

  1. Prototype(原型接口):定义了一个克隆方法,所有具体的原型类都需要实现这个方法。
  2. ConcretePrototype(具体原型) :实现了 Prototype 接口,并且通过 clone 方法来复制自己的实例。
  3. Client(客户端):使用原型对象,并通过调用克隆方法来获取一个新对象,而不是通过构造方法来创建对象。

3. 原型模式的优点

原型模式的优点主要体现在以下几个方面:

  • 性能提升:如果创建对象的过程比较繁琐且需要耗费大量时间,克隆现有对象通常比重新创建一个对象更快。因此,原型模式特别适用于需要大量对象创建的情况,尤其是在构建复杂对象时。

  • 简化对象创建 :使用原型模式可以避免使用 new 关键字显式地创建对象,而是通过克隆一个已有的对象来生成新对象,从而简化了对象的创建过程。

  • 减少内存开销:对于一些复杂的对象,可以通过克隆方式避免重复创建,节省内存空间。比如,当需要创建一个与现有对象类似的多个对象时,原型模式可以避免反复初始化那些相同的属性。

  • 易于扩展:通过增加新的原型类,可以非常方便地扩展对象创建的方式,而不需要修改现有的代码。

4. 原型模式的缺点

原型模式虽然有很多优点,但也有一些缺点和局限:

  • 复杂性:对于某些对象,克隆过程可能会比较复杂。特别是如果对象包含复杂的状态(如对外部资源的引用),克隆对象可能需要更复杂的逻辑,甚至涉及深拷贝(deep copy)。

  • 无法复制某些对象:一些不可复制的对象(例如线程、数据库连接、文件流等)可能无法通过克隆实现,这限制了原型模式的使用场景。

  • 维护问题:在使用原型模式时,如果对象包含复杂的结构,可能会导致对象的一些属性没有完全复制,进而导致逻辑上的问题。特别是在多线程环境中,确保原型对象的一致性会变得更为困难。

5. 原型模式的分类

原型模式可以分为两种主要的克隆方式:

  1. 浅拷贝(Shallow Copy):即仅复制对象的基本类型属性,对于引用类型的属性,只复制引用,而不复制对象本身。这样,源对象和目标对象会共享同一个引用类型的属性。

  2. 深拷贝(Deep Copy):即不仅复制对象的基本类型属性,还会递归地复制引用类型的属性。这样,源对象和目标对象的引用类型属性是完全独立的。

6. 原型模式的应用场景

原型模式适用于以下几种场景:

  • 对象创建开销较大:当创建一个对象非常耗费时间或资源时,使用原型模式可以通过克隆已有对象来避免重复的资源消耗。

  • 对象的属性或状态可以变化,但结构相对固定:如果对象的属性结构较为固定,但又需要动态调整其中的一些属性,可以通过克隆原型来高效地创建新对象。

  • 原型对象有多个副本:在某些场景中,可能需要多个对象具有相同的初始状态(如游戏中的多个相似角色),而通过克隆已有对象来创建副本更为高效。

  • 需要避免重复的复杂对象初始化:当对象的初始化过程非常复杂(如大量的计算和数据加载),原型模式可以通过克隆已有对象来避免重复的计算,减少系统负担。

7. 原型模式的实现示例

以 Java 为例,下面展示一个简单的原型模式实现。

实现具体原型类(ConcretePrototype

我们创建一个具体的原型类 Citation,让他实现Cloneable接口,并重写Object类的 clone 方法。

java 复制代码
public class Citation implements Cloneable{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    protected Citation clone() throws CloneNotSupportedException {
        return (Citation) super.clone();
    }

    public void show(){
        System.out.println(name+"同学获得了奖状");
    }
}
客户端代码(Client

客户端代码通过 clone 方法创建新对象,而无需通过构造方法手动实例化对象。

java 复制代码
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        Citation citation = new Citation();
        citation.setName("张三");

        Citation citation1 = citation.clone();
        citation1.setName("李四");

        citation.show();
        citation1.show();

    }
}
运行结果
复制代码
深拷贝

如果 Citation类中包含一些引用类型的属性,我们可以通过序列化的方式,进行深拷贝。

复制代码
相关推荐
大圣数据星球4 小时前
Fluss 写入数据湖实战
大数据·设计模式·flink
思忖小下5 小时前
梳理你的思路(从OOP到架构设计)_设计模式Template Method模式
设计模式·模板方法模式·eit
思忖小下15 小时前
梳理你的思路(从OOP到架构设计)_简介设计模式
设计模式·架构·eit
liyinuo201717 小时前
嵌入式(单片机方向)面试题总结
嵌入式硬件·设计模式·面试·设计规范
aaasssdddd9619 小时前
C++的封装(十四):《设计模式》这本书
数据结构·c++·设计模式
T1an-119 小时前
设计模式之【观察者模式】
观察者模式·设计模式
思忖小下21 小时前
梳理你的思路(从OOP到架构设计)_设计模式Factory Method模式
设计模式·工厂方法模式·eit
霁月风1 天前
设计模式——工厂方法模式
c++·设计模式·工厂方法模式
发飙的蜗牛'1 天前
23种设计模式
android·java·设计模式
NorthCastle1 天前
设计模式-创建型模式-简单工厂模式详解
设计模式·简单工厂模式