原型模式(Prototype)
时间:2022-04-26
本文章向大家介绍原型模式(Prototype),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
原型模式(Prototype)
原型模式(Prototype)
意图:用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象。
应用:Java/C#中的Clonable和IClonable接口等。
模式结构:
心得:
原型模式本质上就是对象的拷贝,使用对象拷贝代替对象创建的原因有很多。比如对象的初始化构造非常复杂,消耗资源巨大;运行时对象状态变化不可重现;无法获得对象的成员的运行时值等。实现原型模式关键在于对象的正确复制,因此像高级语言实现的那样——支持复制接口。而对象的复制分为“深复制”和“浅复制”,前者除了复制对象本身数据外,还需要复制对象内指针引用的数据,后者则是仅仅复制对象数据。另外,深度复制如果遇到循环引用的对象就会产生问题。
举例:
按照上述设计,这里实现模式的代码如下:
//基本原型接口——相当于Clonable
class Prototype
{
public:
virtual Prototype* Clone()=0;
virtual ~Prototype(){}
};
//原型管理器
class PrototypeMgr
{
hash_map<char*,Prototype*>map;
public:
void regProto(char* key,Prototype*p)
{
if(map.find(key)!=map.end())
{
delete map[key];
}
map[key]=p;
}
Prototype* const operator[](char* key)
{
if(map.find(key)!=map.end())
{
return map[key]->Clone();
}
else
return NULL;
}
~PrototypeMgr()
{
for(hash_map<char*,Prototype*>::iterator it=map.begin();
it!=map.end();++it)
{
delete it->second;
}
}
};
//浅拷贝
class ConcretePrototype1:public Prototype
{
int * refMember;
int member;
public:
virtual Prototype* Clone()
{
cout<<"执行ConcretePrototype1的浅复制"<<endl;
ConcretePrototype1*copy= new ConcretePrototype1;
copy->member=member;
copy->refMember=refMember;
return copy;
}
};
//深度拷贝
class ConcretePrototype2:public Prototype
{
int * refMember;
int member;
public:
ConcretePrototype2():refMember(new int){}
virtual Prototype* Clone()
{
cout<<"执行ConcretePrototype2的深复制"<<endl;
ConcretePrototype2*copy= new ConcretePrototype2;
copy->member=member;
copy->refMember=new int;//指针引用数据也要拷贝
*copy->refMember=*refMember;
return copy;
}
virtual~ConcretePrototype2()
{
delete refMember;
}
};
这里添加一个原型管理器,用来管理所有的注册的原型。用户需要拷贝出原型只需要从这里请求即可。
PrototypeMgr mgr;
//注册原型
mgr.regProto("浅复制",new ConcretePrototype1);
mgr.regProto("深复制",new ConcretePrototype2);
//请求原型
Prototype*cp1=mgr["浅复制"];
Prototype*cp2=mgr["深复制"];
delete cp1;
delete cp2;
参考文章:http://zxyjxnu.blog.163.com/blog/static/1330787122007103095839612/
- PhalGo-介绍
- 实测Nginx服务器开启pagespeed加速效果
- MySQL频繁停库的问题分析(r12笔记第33天)
- 解决Nginx Helper插件一键清理缓存功能导致网站打不开问题
- Oracle 12c DBCA浅析(r12笔记第48天)
- MySQL中的derived table(r12笔记第47天)
- Oracle数据库端口突然无法访问的分析(r12笔记第46天)
- MySQL中的反连接(r12笔记第45天)
- Nginx配置多站点下的Proxy_cache或Fastcgi_cache缓存加速
- MySQL主从不一致的细小问题分析(r12笔记第62天)
- Linux在批量服务器管理中实用的PS1命令提示符格式
- Golang语言社区-并发模型和应用场景
- 翻过那座山,就能看见海|kubernetes让DBA更优雅地管理数据库
- 基于TextCNN的谩骂评论识别模型
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android onCreateOptionsMenu的使用方法总结
- android截图事件监听的原理与实现
- 我常用的一些linux命令小结
- linux下安装mongodb教程
- Android中使用TagFlowLayout制作动态添加删除标签
- Android时间对话框使用方法详解
- Ubuntu基础设定:openssh-server的安装和使用介绍
- Android ProgressDialog的实例详解
- linux下获取文件的创建时间与实战教程
- Android 判断网络状态及开启网路
- Android判断后台服务是否开启的两种方法实例详解
- 在CentOS7上搭建Jenkins+Maven+Git持续集成环境的方法
- Linux 实现定时文件占用磁盘空间大小操作方法
- Android开发之文件操作详解
- Linux查看服务器硬件信息的方法步骤