【设计模式】——原型模式(Prototype Patter)

目录

引言

一、原型模式的基本概念

核心思想

原型模式结构

UML图

应用场景

二、原型模式的优点与缺点

优点

缺点

三、C++实现原型模式

1. 定义抽象原型类

2. 定义具体原型类

3. 客户端代码

4. 总代码

四、总结


引言

在软件开发中,设计模式是解决常见问题的最佳实践集合。原型模式(Prototype Pattern)作为创建型设计模式之一,提供了一种通过复制现有对象来创建新对象的方式,从而避免了在创建新对象时执行复杂的初始化过程。这种模式在处理大量相似对象的创建时特别有用,能够显著提高性能并减少资源消耗。

一、原型模式的基本概念

原型模式通过给出一个原型对象来指明所要创建的对象的类型,然后用拷贝这个原型对象的方法来创建出更多同类型的对象。简言之,它利用已有的对象实例(称为“原型”)来创建新的对象实例。

核心思想

原型模式的核心思想是通过复制一个已存在的对象(原型)来创建新的对象,而不是通过实例化类来创建。这种复制可以是浅拷贝(只复制对象的基本数据类型成员和引用类型成员的引用,不复制引用类型成员本身),也可以是深拷贝(完全复制对象及其所有成员,包括引用类型成员本身)。

原型模式结构

原型模式通常包含以下几个主要角色:

  1. 抽象原型(Prototype):声明了一个克隆自身的接口,即一个拷贝自身的抽象方法。这个接口是所有具体原型类的公共父类或接口。

  2. 具体原型(Concrete Prototype):实现了克隆自身的接口,即实现了拷贝自身的具体方法。这个方法是创建对象副本的关键。

  3. 客户端(Client):通过调用具体原型的克隆方法来创建新的对象实例。客户端不直接通过new关键字来创建对象,而是通过原型对象的克隆方法来获取新对象。

UML图

应用场景

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

  • 当一个对象初始化需要消耗较多资源时,如读取大量数据、进行复杂计算等。
  • 当需要创建的对象数量较大,且这些对象具有相似的状态时。
  • 当对象的创建过程较为复杂,且需要避免在构造函数中执行这些复杂操作时。
  • 当系统中存在大量相似对象,且这些对象的状态需要频繁变更时。

二、原型模式的优点与缺点

优点

  1. 性能提升:通过复制现有对象来创建新对象,比通过构造函数创建对象要快,特别是在对象创建过程复杂或耗时时。

  2. 简化对象创建:减少了对象创建过程中的复杂性,特别是在需要频繁创建具有相似状态的对象时。

  3. 灵活性:允许在运行时动态地创建对象,并可以灵活地调整对象的属性。

  4. 原型可复用:原型对象本身可以被多次用来创建新对象,提高了代码的复用性。

  5. 支持深拷贝和浅拷贝:根据需求选择实现深拷贝或浅拷贝,以满足不同的场景需求。

缺点

  1. 深浅拷贝问题:默认实现通常是浅拷贝,可能导致对象状态的不一致性,特别是在对象包含引用类型成员时。需要特别注意实现深拷贝以避免这个问题。

  2. 需要实现克隆方法:每个需要使用原型模式的类都必须实现克隆方法,增加了类的复杂性。如果类的结构复杂,克隆方法的实现可能会变得复杂。

  3. 破坏封装性:在某些情况下,克隆方法可能需要访问对象的内部状态,这可能会破坏对象的封装性。需要在实现时权衡封装性和便利性。

  4. 适用场景有限:虽然原型模式在某些场景下非常有用,但它并不适用于所有情况。需要根据具体情况选择最合适的设计模式。

综上所述,原型模式是一种强大的设计模式,它提供了灵活、高效的对象创建方式。然而,在使用时也需要注意其优缺点,并根据实际情况进行权衡和选择。

三、C++实现原型模式

在C++中,实现原型模式通常涉及到重写clone()方法(或使用C++11中的拷贝控制成员,如拷贝构造函数和拷贝赋值运算符)。下面是一个简单的C++示例,演示了原型模式的实现:

1. 定义抽象原型类

// 抽象原型类  
class Dog {  
public:  
    virtual ~Dog() {}  
    virtual Dog* clone() const = 0; // 克隆方法  
    virtual void play() const = 0; // 其他公共接口  
};  

2. 定义具体原型类

// 具体原型类  
class Twoha : public Dog {  
public:  
    Twoha(string name) : name(name) {}  
  
    // 实现克隆方法  
    Dog* clone() const override {  
        return new Twoha(*this); // 使用拷贝构造函数进行深拷贝  
    }  
  
    // 实现其他公共接口  
    void play() const override {  
        cout << "你是一只" << name << endl;  
    }  
  
private:  
    string name;  
};

3. 客户端代码

int main() {  
    Dog* dog = new Twoha("二哈");  
    Dog* Eha1 = dog->clone();  
    Dog* Eha2 = dog->clone();  
  
    Eha1->play();  
    Eha2->play();  
  
    delete dog;  
    delete Eha1;  
    delete Eha2;  
  
    return 0;  
}

4. 总代码

Dog类是一个抽象原型类,它定义了一个clone()方法和一个play()方法。Twoha类是一个具体原型类,它实现了Dog类的clone()play()方法。clone()方法通过拷贝构造函数实现了深拷贝,从而保证了新对象的独立性。

#include <iostream>  
#include <string>  
using namespace std;  
  
// 抽象原型类  
class Dog {  
public:  
    virtual ~Dog() {}  
    virtual Dog* clone() const = 0; // 克隆方法  
    virtual void play() const = 0; // 其他公共接口  
};  
  
// 具体原型类  
class Twoha : public Dog {  
public:  
    Twoha(string name) : name(name) {}  
  
    // 实现克隆方法  
    Dog* clone() const override {  
        return new Twoha(*this); // 使用拷贝构造函数进行深拷贝  
    }  
  
    // 实现其他公共接口  
    void play() const override {  
        cout << "你是一只" << name << endl;  
    }  
  
private:  
    string name;  
};  
  
int main() {  
    Dog* dog = new Twoha("二哈");  
    Dog* Eha1 = dog->clone();  
    Dog* Eha2 = dog->clone();  
  
    Eha1->play();  
    Eha2->play();  
  
    delete dog;  
    delete Eha1;  
    delete Eha2;  
  
    return 0;  
}

四、总结

原型模式是一种通过克隆现有对象来创建新对象的设计模式。它提供了灵活、高效的对象创建方式,可以在某些场景下显著提高代码的复用性和可维护性。然而,使用时也需要注意深浅拷贝的问题,以及克隆方法可能带来的封装性破坏。在C++中,通过重写clone()方法或使用拷贝构造函数,可以轻松实现原型模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

J^T

谢谢帅哥/美女

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值