23种设计模式-原型(Prototype)设计模式

文章目录

类图: 原型设计模式类图

一.什么是原型设计模式?

原型模式 (Prototype Pattern) 是一种创建型设计模式,它通过复制现有对象来生成新对象,而不是通过实例化类来创建。这种模式基于对象的克隆机制,适用于需要频繁创建对象的场景,可以提高性能并减少复杂的初始化过程。

二.原型模式的特点

  • 克隆对象:通过复制已有对象生成新对象,而非通过构造函数创建。
  • 性能优化:避免复杂对象创建的高开销。
  • 灵活性:可以动态添加或删除原型,而不影响其他对象。

三.原型模式的结构

  • Prototype(抽象原型类):定义了克隆方法,通常是 clone() 方法。
  • ConcretePrototype(具体原型类):实现抽象原型类的克隆方法。
  • Client(客户端):调用克隆方法创建新对象,而无需关心对象的具体类型。

四.原型模式的优缺点

  • 优点:
    • 性能优势:克隆比重新创建对象效率更高。
    • 动态性:无需编译时依赖类,可以在运行时动态生成对象。
    • 避免依赖性:通过克隆机制,可以避免直接依赖类的构造函数。
  • 缺点:
    • 复杂性增加:需要正确实现克隆方法,尤其是深拷贝场景。
    • 资源消耗:可能会为每个可克隆的对象维护克隆逻辑,导致类职责增多。

五.原型模式的 C++ 实现

cpp 复制代码
#include <iostream>
#include <string>
#include <memory> // for smart pointers
using namespace std;

// 抽象原型类
class Prototype {
public:
    virtual ~Prototype() = default;

    // 克隆方法(纯虚函数)
    virtual unique_ptr<Prototype> clone() const = 0;

    virtual void display() const = 0;
};

// 具体原型类1
class ConcretePrototypeA : public Prototype {
private:
    string data; // 模拟一些状态
public:
    ConcretePrototypeA(string data) : data(data) {}

    // 克隆方法
    unique_ptr<Prototype> clone() const override {
        return make_unique<ConcretePrototypeA>(*this); // 调用拷贝构造函数
    }

    void display() const override {
        cout << "ConcretePrototypeA with data: " << data << endl;
    }
};

// 具体原型类2
class ConcretePrototypeB : public Prototype {
private:
    int value; // 模拟一些状态
public:
    ConcretePrototypeB(int value) : value(value) {}

    // 克隆方法
    unique_ptr<Prototype> clone() const override {
        return make_unique<ConcretePrototypeB>(*this); // 调用拷贝构造函数
    }

    void display() const override {
        cout << "ConcretePrototypeB with value: " << value << endl;
    }
};

// 客户端代码
void ClientCode(const Prototype& prototype) {
    auto clonedObject = prototype.clone(); // 克隆一个对象
    clonedObject->display();               // 显示克隆对象的内容
}

int main() {
    // 创建原型对象
    ConcretePrototypeA prototypeA("PrototypeA Data");
    ConcretePrototypeB prototypeB(42);

    cout << "Cloning ConcretePrototypeA:" << endl;
    ClientCode(prototypeA);

    cout << "\nCloning ConcretePrototypeB:" << endl;
    ClientCode(prototypeB);

    return 0;
}

六.原型模式的 Java 实现

java 复制代码
// 抽象原型类
abstract class Prototype implements Cloneable {
    public abstract Prototype clone();

    public abstract void display();
}

// 具体原型类A
class ConcretePrototypeA extends Prototype {
    private String data;

    public ConcretePrototypeA(String data) {
        this.data = data;
    }

    @Override
    public Prototype clone() {
        try {
            return (Prototype) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException("Clone not supported!");
        }
    }

    @Override
    public void display() {
        System.out.println("ConcretePrototypeA with data: " + data);
    }
}

// 具体原型类B
class ConcretePrototypeB extends Prototype {
    private int value;

    public ConcretePrototypeB(int value) {
        this.value = value;
    }

    @Override
    public Prototype clone() {
        try {
            return (Prototype) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException("Clone not supported!");
        }
    }

    @Override
    public void display() {
        System.out.println("ConcretePrototypeB with value: " + value);
    }
}

// 客户端代码
public class PrototypePatternExample {
    public static void main(String[] args) {
        // 创建原型对象
        ConcretePrototypeA prototypeA = new ConcretePrototypeA("PrototypeA Data");
        ConcretePrototypeB prototypeB = new ConcretePrototypeB(42);

        System.out.println("Cloning ConcretePrototypeA:");
        Prototype clonedA = prototypeA.clone();
        clonedA.display();

        System.out.println("\nCloning ConcretePrototypeB:");
        Prototype clonedB = prototypeB.clone();
        clonedB.display();
    }
}

七. 代码解析

  • 抽象原型类(Prototype)
    • 定义了一个 clone() 方法,用于生成当前对象的副本。
    • 使用虚函数,使得派生类可以实现自己的克隆逻辑。
  • 具体原型类(ConcretePrototypeA 和 ConcretePrototypeB)
    • 实现了 clone() 方法,通过调用自身的拷贝构造函数完成对象的克隆。
    • ConcretePrototypeA 和 ConcretePrototypeB 模拟了不同的数据成员,演示了克隆不同类型对象的效果。
  • 客户端代码
    • 接收一个 Prototype 对象的引用,并通过调用 clone() 方法克隆出一个新对象。
    • 客户端无需关心具体的类,只需通过 Prototype 接口调用克隆方法即可。

八.总结

原型模式通过克隆的方式创建新对象,而不依赖于类的构造函数。这种模式在需要频繁创建对象、或者需要动态生成对象的场景中非常有用。通过正确实现 clone() 方法,可以有效提高程序的灵活性和性能。然而,在实现复杂对象的深拷贝时,需要特别注意对象之间的依赖关系和资源管理,以避免潜在的错误。
应用场景:

  • 复杂对象的创建:初始化需要耗费大量资源的对象可以通过克隆来生成新对象。
  • 性能优化:避免使用构造函数或工厂方法重复创建对象。
  • 动态对象管理:需要动态生成对象而不依赖具体类。
相关推荐
轩情吖16 分钟前
C++类型转换
java·开发语言·c++·多态·c++类型转换·rtti
爱吃涮毛肚的肥肥(暂时吃不了版)17 分钟前
数据结构与算法——1127—异或^&&
开发语言·数据结构·c++·算法
Langkaixin26 分钟前
idea编译与maven编译的问题
java·maven·intellij-idea
兩尛33 分钟前
搜索二维矩阵 II(java)
java·算法·矩阵
岁岁岁平安1 小时前
JavaWeb实战(1)(重点:分页查询、jstl标签与jsp、EL表达式、Bootstrap组件搭建页面、jdbc)
java·servlet·javaweb·jsp·el·分页查询·jstl
erxij1 小时前
【游戏引擎之路】登神长阶(十五)——DirectX12龙书:行百里者半九十(学习阶段完结)
c++·经验分享·学习·游戏·3d·游戏引擎
java_upp1 小时前
简简单单实现java系统调用WebServie接口
java·webservice
Allen Bright1 小时前
【maven-4】IDEA 配置本地 Maven 及如何使用 Maven 创建 Java 工程
java·maven·intellij-idea
考虑考虑1 小时前
JDK8加载拓展包
java·后端·java ee
南风不竞~~2 小时前
Maven 配置
java·maven