prototype pattern--原型模式
prototype pattern称为原型模式
在软件系统中,经常面临着“某些结构复杂的对象”的创建工作,由于需求的变化,这些对象经常面临着剧烈的变化,但是他们却拥有比较稳定一致的接口。Prototype设计模式,就是为了解决如何向“客户程序”隔离出“这些易变对象”,从而使得“依赖这些易变对象的客户程序”不随着需求的改变而改变。
Prototype设计模式指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。
要点:
- Prototype设计模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些“易变类”拥有“稳定的接口”。
- Prototype设计模式对于“如何创建易变类的实体对象”采用“原型克隆”的方法来做,它使得我们可以非常灵活地动态创建“拥有某些稳定接口”的新对象,所需要的工作仅仅是注册一个新类的对象(即原型),然后在需要的地方不断地Clone
- Clone时要注意使用Deep Clone。
深拷贝与浅拷贝区别:
浅拷贝也称位拷贝,就是对象的数据成员之间的简单赋值,例如一个类我们没有具体定义其拷贝构造函数当用该类的一个对象去给令一个对象赋值时所执行的过程就是浅拷贝。
如果对象中没有其他的资源(如:堆,文件,系统资源等),则深拷贝和浅拷贝没有什么区别,但是如果有那么浅拷贝只是简单的引用这些资源,而深拷贝是会复制这些资源的。
举例说明:
1 class People 2 { 3 public: 4 People(Hair *ha,int a) 5 :h(ha),age(a) 6 {} 7 private: 8 Hair *h; 9 int age; 10 }; 11 Hair * ha=new Hair(....); 12 People p1(ha,a); 13 People p2=p1;//浅拷贝 p2.h=p1.h, p2.age=p1.age
那么如果是浅拷贝(位拷贝)只是简单的将Hair *h指针指向ha指针指向的资源。那么这里想象下这里如果在销毁p1的时候我们会释放p1.h所指向的资源,那么在使用p2就会发生错误!!所以我们平常应该尽量少使用浅拷贝,这会给程序带来危害。
当然从这里我们也可以得知,如果没有资源,深浅拷贝是没有任何区别的。
下面接着看原型模式:
1 class wheel 2 { 3 public: 4 wheel(std::string n,int l) 5 :name(n),loadCapacity(l) 6 {} 7 wheel( ) 8 :name(""),loadCapacity(0) 9 {} 10 void show(); 11 wheel * Clone(); 12 private: 13 std::string name; 14 int loadCapacity; 15 }; 16 void wheel::show( ) 17 { 18 std::cout<<"The wheel name is "<<name<<std::endl; 19 std::cout<<"The wheel loadCapacity is "<<loadCapacity<<std::endl; 20 } 21 22 wheel * wheel::Clone() 23 { 24 return new wheel(name,loadCapacity); 25 } 26 27 class Car 28 { 29 public: 30 Car(std::string color,wheel* w,std::string engine) 31 32 :_color(color),_wheel(w),_engine(engine) 33 {} 34 virtual Car* Clone( )=0; 35 virtual void Show( )=0; 36 virtual void setColor(std::string color )=0; 37 virtual ~Car( ){} 38 protected: 39 std::string _color; 40 //有一个资源 41 wheel* _wheel; 42 std::string _engine; 43 }; 44 45 class BenzCar:public Car 46 { 47 public: 48 BenzCar(std::string color,wheel *w,std::string engine) 49 :Car(color,w,engine) 50 { } 51 ~BenzCar( ); 52 void Show( ); 53 Car * Clone( ); 54 void setColor( std::string color ); 55 }; 56 57 BenzCar::~BenzCar( ) 58 { 59 delete _wheel; 60 } 61 Car* BenzCar::Clone( ) 62 { 63 wheel* l=_wheel.Clone( ); 64 Car * pc=new BenzCar(_color,l, _engine ); 65 return pc; 66 } 67 void BenzCar::Show( ) 68 { 69 std::cout<<"The car's color is"<<_color<<std::endl; 70 _wheel.show( ); 71 std::cout<<"The car's engine is"<<_engine<<std::endl; 72 } 73 74 void BenzCar::setColor(std::string color ) 75 { 76 _color=color; 77 } 78 79 int main(int argc,char ** argv) 80 { 81 wheel *l=new wheel("michelin",160); 82 BenzCar bc("red",l,"made in China"); 83 std::auto_ptr<Car> pc(bc.Clone( )); 84 pc-set("white"); 85 pc->Show( ); 86 bc->Show( ); 87 return 0; 88 }
运行结果: