原型模式
Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype.
(用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。)
不通过new关键字产生一个对象,而是通过对象复制来实现的模式叫做原型模式。
通用源码
C++可以重写拷贝构造函数实现对象的复制
java需要依赖Cloneable接口重写clone函数,如:
public class PrototypeClass implements Cloneable {
@Override
public PrototypeClass clone() {
PrototypeClass prototypeClass = null;
try {
prototypeClass = (PrototypeClass) super.clone();
} catch(CloneNotSupportedException e) {
//异常处理
}
return prototypeClass;
}
}
优点
性能优良,是内存二进制流的拷贝,比new对象的性能好很多
逃避构造函数的约束
使用场景
资源优化场景,初始化需要消耗非常多的资源时
性能和安全要求的场景,通过new产生镀锡需要非常繁琐的数据准备或访问权限时
一个对象多个修改者的场景
注意事项
构造函数不会被执行
深拷贝和浅拷贝,不会被拷贝的成员变量:类的成员变量;可变的引用对象;
使用clone方法,类的成员变量不要增加final关键字,否则会产生冲突
示例代码
#include <iostream>
#include <string>
using namespace std;
class AdvTemplate {
private:
const string advSubject = "xx银行国庆信用卡抽奖活动";
const string advContext = "国庆抽奖活动通知:只要刷卡就送你一百万!...";
public:
string getAdvSubject() {
return advSubject;
}
string getAdvContext() {
return advContext;
}
};
class Mail {
private:
string receiver;
string subject;
string appellation;
string context;
string tail;
public:
Mail(AdvTemplate advTemplate) {
context = advTemplate.getAdvContext();
subject = advTemplate.getAdvSubject();
}
Mail(const Mail &mail) {
receiver = mail.receiver;
subject = mail.subject;
appellation = mail.appellation;
context = mail.context;
tail = mail.tail;
}
string getReceiver() {
return receiver;
}
void setReceiver(string &s) {
receiver = s;
}
string getSubject() {
return subject;
}
void setSubject(string &s) {
subject = s;
}
string getAppellation() {
return appellation;
}
void setAppellation(string &s) {
appellation = s;
}
string getContext() {
return context;
}
void setContext(string &s) {
context = s;
}
string getTail() {
return tail;
}
void setTail(string &s) {
tail = s;
}
};
void sendMail(Mail &mail) {
cout << "title: " << mail.getSubject() << "\treceiver: " << mail.getReceiver()
<< "\t...send successful!" << endl;
}
string getRandString() {
static int n = 0;
string source = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
string name = source.substr(n, 5);
n+=5;
return name;
}
int main() {
int nums = 3;
string tail = "xx银行版权所有";
Mail mail = Mail(AdvTemplate());
mail.setTail(tail);
while(nums != 0) {
string name = getRandString();
name.append("先生(女士)");
mail.setAppellation(name);
string receiver = getRandString();
receiver.append("@test");
mail.setReceiver(receiver);
Mail clonemail = Mail(mail);
sendMail(clonemail);
nums--;
}
return 0;
}