【设计模式】【创建型模式(Creational Patterns)】之原型模式(Prototype Pattern)
1. 设计模式原理说明
原型模式(Prototype Pattern) 是一种创建型设计模式,它允许你通过复制现有对象来创建新对象,而无需通过构造函数来创建。这种方式可以提高性能,尤其是在对象初始化需要消耗大量资源或耗时较长的情况下。原型模式的关键在于对象的克隆方法,通过该方法可以创建一个与原对象具有相同属性的新对象。
主要角色
- Prototype(抽象原型类):声明了克隆自身的接口。
- ConcretePrototype(具体原型类):实现了克隆方法,用于创建新的对象实例。
- Client(客户端):使用原型类创建新对象。
2. UML 类图及解释
UML 类图
+----------------+ +---------------------+
| Prototype | | ConcretePrototype |
|----------------| |---------------------|
| + clone(): Prototype | + clone(): Prototype|
+----------------+ +---------------------+
+----------------+ |
| Client | |
|----------------| |
| - prototype: Prototype |
| +---------+
| + createClone(): Prototype |
| + mainMethod(): void |
+----------------+ |
类图解释
- Prototype:定义了一个克隆自身的接口。这个接口通常是一个
clone
方法,用于创建一个新的对象实例。 - ConcretePrototype:实现了
Prototype
接口中定义的clone
方法,用于创建新的对象实例。具体的克隆逻辑由具体原型类实现。 - Client:使用原型类创建新对象。客户端持有一个原型对象的引用,并通过调用其
clone
方法来创建新的对象实例。
3. 代码案例及逻辑详解
Java 代码案例
// 抽象原型类
interface Prototype {
Prototype clone();
}
// 具体原型类
class ConcretePrototype implements Prototype {
private String value;
public ConcretePrototype(String value) {
this.value = value;
}
@Override
public Prototype clone() {
// 浅拷贝
return new ConcretePrototype(this.value);
}
@Override
public String toString() {
return "ConcretePrototype [value=" + value + "]";
}
}
// 客户端
class Client {
private Prototype prototype;
public Client(Prototype prototype) {
this.prototype = prototype;
}
public Prototype createClone() {
return prototype.clone();
}
public static void main(String[] args) {
ConcretePrototype original = new ConcretePrototype("Original Value");
Client client = new Client(original);
ConcretePrototype clone1 = (ConcretePrototype) client.createClone();
ConcretePrototype clone2 = (ConcretePrototype) client.createClone();
System.out.println("Original: " + original);
System.out.println("Clone 1: " + clone1);
System.out.println("Clone 2: " + clone2);
}
}
C++ 代码案例
#include <iostream>
#include <string>
// 抽象原型类
class Prototype {
public:
virtual Prototype* clone() const = 0;
virtual ~Prototype() {}
};
// 具体原型类
class ConcretePrototype : public Prototype {
private:
std::string value;
public:
ConcretePrototype(const std::string& value) : value(value) {}
Prototype* clone() const override {
return new ConcretePrototype(*this);
}
friend std::ostream& operator<<(std::ostream& os, const ConcretePrototype& p) {
return os << "ConcretePrototype [value=" << p.value << "]";
}
};
// 客户端
class Client {
private:
Prototype* prototype;
public:
Client(Prototype* prototype) : prototype(prototype) {}
Prototype* createClone() {
return prototype->clone();
}
~Client() {
delete prototype;
}
};
int main() {
ConcretePrototype original("Original Value");
Client client(&original);
ConcretePrototype* clone1 = dynamic_cast<ConcretePrototype*>(client.createClone());
ConcretePrototype* clone2 = dynamic_cast<ConcretePrototype*>(client.createClone());
std::cout << "Original: " << original << std::endl;
std::cout << "Clone 1: " << *clone1 << std::endl;
std::cout << "Clone 2: " << *clone2 << std::endl;
delete clone1;
delete clone2;
return 0;
}
Python 代码案例
import copy
# 抽象原型类
class Prototype:
def clone(self):
pass
# 具体原型类
class ConcretePrototype(Prototype):
def __init__(self, value):
self.value = value
def clone(self):
# 使用深拷贝
return copy.deepcopy(self)
def __str__(self):
return f"ConcretePrototype [value={self.value}]"
# 客户端
class Client:
def __init__(self, prototype):
self.prototype = prototype
def create_clone(self):
return self.prototype.clone()
if __name__ == "__main__":
original = ConcretePrototype("Original Value")
client = Client(original)
clone1 = client.create_clone()
clone2 = client.create_clone()
print("Original:", original)
print("Clone 1:", clone1)
print("Clone 2:", clone2)
Go 代码案例
package main
import (
"fmt"
)
// 抽象原型类
type Prototype interface {
Clone() Prototype
}
// 具体原型类
type ConcretePrototype struct {
Value string
}
func (p *ConcretePrototype) Clone() Prototype {
// 浅拷贝
return &ConcretePrototype{Value: p.Value}
}
func (p *ConcretePrototype) String() string {
return fmt.Sprintf("ConcretePrototype [value=%s]", p.Value)
}
// 客户端
type Client struct {
prototype Prototype
}
func NewClient(prototype Prototype) *Client {
return &Client{prototype: prototype}
}
func (c *Client) CreateClone() Prototype {
return c.prototype.Clone()
}
func main() {
original := &ConcretePrototype{Value: "Original Value"}
client := NewClient(original)
clone1 := client.CreateClone().(*ConcretePrototype)
clone2 := client.CreateClone().(*ConcretePrototype)
fmt.Println("Original:", original)
fmt.Println("Clone 1:", clone1)
fmt.Println("Clone 2:", clone2)
}
4. 总结
原型模式 是一种创建型设计模式,它通过复制现有对象来创建新对象,而不是通过构造函数。这种方式可以提高性能,特别是在对象初始化需要消耗大量资源或耗时较长的情况下。原型模式的主要优点包括:
- 性能提升:通过复制现有对象来创建新对象,可以避免复杂的初始化过程,提高性能。
- 代码简洁:减少了重复的代码,特别是当对象的初始化过程非常复杂时。
- 灵活度高:可以通过修改原型对象的属性来创建不同配置的对象实例。
然而,原型模式也有一些缺点,例如:
- 深拷贝和浅拷贝的问题:需要仔细处理对象的深拷贝和浅拷贝问题,否则可能会导致意外的行为。
- 类必须实现克隆方法:每个需要被克隆的类都必须实现
clone
方法,这可能会增加代码的复杂性。
总的来说,原型模式在需要频繁创建相似对象的场景中非常有用,但在简单对象的创建中可能显得过于复杂。选择是否使用原型模式应根据具体的需求和场景来决定。
原文地址:https://blog.csdn.net/ido1ok/article/details/144059730
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!