http://blog.csdn.net/lovelion/article/details/17517213
我做的这部分笔记,鉴于自身水平有限,我只是对上面博客内做进一步提炼和记录,方便自己查阅。同时,更多的是对设计模式的框架进行学习,大部分细节都将略去,让自己侧重对每个设计模式框架的理解。
我应该理解和掌握的:
1)能够画出这个设计模式的架构框图;
2)能够根据架构框图写出对应的伪代码;
3)这个模式的应用场景,主要优缺点。
1.原型模式
(1)定义
原型模式:使用原型实例指定创建的种类,并且通过拷贝这些原型模式创建新的对象。通过Clone出的对象是全新的对象,他们在内存中拥有全新的地址,通常对克隆所产生的对象进行修改对原型对象不会造成任何影响,每一个克隆对象都是相对独立的。
下面给出模式结构图:
参与者:
1)Prototype(抽象原型类):声明克隆方法的接口或者基类。
2)ConcretePrototype(具体原型类):实现一个克隆自身的操作,返回一个自己的克隆对象。
3)Client(客户类):让一个原型克隆自身从而创建一个新的对象。
4)核心在于如何实现克隆方法。
看图写代码:
class Prototype
{
public:
virtual Prototype* clone() = 0;
virtual void show() = 0;
};
//子类
class ConcreteProtype:public Prototype
{
public:
Prototype* clone();
ConcreteProtype();
ConcreteProtype(const char* str);
ConcreteProtype(const ConcreteProtype & p);//拷贝构造函数
virtual ~ConcreteProtype();
virtual void show();
private:
char *s;
};
//实现
#include "ConcreteProtype.h"
Prototype* ConcreteProtype::clone() //克隆
{
return new ConcreteProtype(*this); //调用拷贝构造函数
}
ConcreteProtype::ConcreteProtype(const char* str)
{
if(str == NULL)
{
s = new char[1];
s[0] = '\0';
}
else
{
s = new char[strlen(str) + 1];
strcpy(s, str);
}
}
ConcreteProtype::ConcreteProtype(const ConcreteProtype & p)
{
s = new char[strlen(p.s) + 1];
strcpy(s, p.s);
}
ConcreteProtype::ConcreteProtype()
{
}
ConcreteProtype::~ConcreteProtype()
{
delete [] s;
}
void ConcreteProtype::show()
{
cout<<s<<"\n";
}
//客户端测试
int main()
{
//原型
Prototype* pt = new ConcreteProtype("samsung");
//克隆
Prototype* pt_clone = pt->clone();
pt->show();
delete pt;
pt = NULL;
//深拷贝
pt_clone->show();
delete pt_clone;
pt_clone = NULL;
return 0;
}
(2)总结
1)当创建的对象较为复杂时,使用原型模式可以简化对象的创建过程,通过复制一个已有的实例提高效率。
2)扩展性好,客户端针对抽象原型编程。
3)简化创建结构,工厂方法需要一个与产品等级相对应的等级层次工厂类,而原型模式就不用。
4)可以使用深克隆的方式保存对象状态,使用原型模式将对象复制一份保存起来,以便在需要的时候使用。
5)克隆的时候,注意是浅克隆还是深克隆。深克隆时较为复杂,特别是对象之间存在多重嵌套引用时。
6)缺点是需要为每个类配备一个克隆方法,而且克隆方法位于类内部,当对已有的类进行改造时,需要修改源代码,违背开闭原则。
(3)使用场景
1)当一个系统应该独立于他的产品创建、构成和表示时;
2)为了避免创建一个与产品类层次平行的工厂层次时;
3)当要实例化的类是在运行时刻指定时;
4)当一个类的实例只能有几个不同状态组合中的一种时,建立相应数目的原型并克隆他们可能比每次用合适的状态手工实例化该类更为方便。