概述
- 动机:“某些结构复杂对象”的创建工作,由于需求的变化,这些对象面临剧烈的变化,但它们却拥有比较稳定一致的接口
- 如何应对这种变化,如何向“客户程序(使用这些对象的程序)”隔离出“这些易变对象”,从而使得“依赖这些易变对象的客户程序”不随着需求改变而改变
- 使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象
- 通过克隆自己创建对象(拷贝构造函数)
- 原型对象用于克隆新对象,不能使用
- 相当于工厂模式中,把工厂抽象类和业务抽象类合并
- 同样用于隔离类对象的使用者和具体类型(易变类)间的耦合关系,它同样要求这些“易变类”拥有“稳定的接口”
- 对于“如何创建易变类的实体对象”采用“原型克隆”的方法来做,使我们可以非常灵活地创建“拥有某些稳定接口”的新对象,所需工作仅是注册一个新的对象(即原型),然后在任何需要的地方Clone
- Clone方法可利用某些框架中的序列化来实现深拷贝
示例1
Client.cpp
1 class MainForm : public Form 2 { 3 ISplitter* prototype;//原型对象 4 5 public: 6 7 MainForm(ISplitter* prototype){ 8 this->prototype=prototype; 9 } 10 11 void Button1_Click(){ 12 13 ISplitter * splitter= 14 prototype->clone(); //克隆原型 15 16 splitter->split(); 17 18 } 19 };
Prototype.cpp
1 //抽象类 2 class ISplitter{ 3 public: 4 virtual void split()=0; 5 virtual ISplitter* clone()=0; //通过克隆自己来创建对象 6 virtual ~ISplitter(){} 7 };
ConcretePrototype.cpp
1 //具体类 2 class BinarySplitter : public ISplitter{ 3 public: 4 virtual ISplitter* clone(){ 5 return new BinarySplitter(*this); 6 } 7 }; 8 9 class TxtSplitter: public ISplitter{ 10 public: 11 virtual ISplitter* clone(){ 12 return new TxtSplitter(*this); 13 } 14 }; 15 16 class PictureSplitter: public ISplitter{ 17 public: 18 virtual ISplitter* clone(){ 19 return new PictureSplitter(*this); 20 } 21 }; 22 23 class VideoSplitter: public ISplitter{ 24 public: 25 virtual ISplitter* clone(){ 26 return new VideoSplitter(*this); 27 } 28 };
示例2
- 带原型管理器的原型模式(java)
1 package Clone; 2 3 import java.util.HashMap; 4 import java.util.Scanner; 5 6 interface Shape extends Cloneable 7 { 8 public Object clone(); 9 public void countArea(); 10 } 11 12 class Circle implements Shape 13 { 14 public Object clone() 15 { 16 Circle w=null; 17 try 18 { 19 w=(Circle)super.clone(); 20 } 21 catch(CloneNotSupportedException e) 22 { 23 System.out.println("拷贝圆失败!"); 24 } 25 return w; 26 } 27 public void countArea() 28 { 29 int r=0; 30 System.out.print("这是一个圆,请输入半径:"); 31 Scanner input=new Scanner(System.in); 32 r=input.nextInt(); 33 System.out.println("该圆的面积="+3.14*r*r+" "); 34 } 35 } 36 37 class Square implements Shape 38 { 39 public Object clone() 40 { 41 Square b=null; 42 try 43 { 44 b=(Square)super.clone(); 45 } 46 catch(CloneNotSupportedException e) 47 { 48 System.out.println("拷贝方形失败!"); 49 } 50 return b; 51 } 52 public void countArea() 53 { 54 int a=0; 55 System.out.println("这是一个正方形,请输入它的边长:"); 56 Scanner input=new Scanner(System.in); 57 a=input.nextInt(); 58 System.out.println("该正方形的面积="+a*a+" "); 59 } 60 } 61 62 class ProtoTypeManager 63 { 64 private HashMap<String,Shape>ht=new HashMap<String,Shape>(); 65 public ProtoTypeManager() 66 { 67 ht.put("Circle", new Circle()); 68 ht.put("Square", new Square()); 69 } 70 public void addshape(String key,Shape obj) 71 { 72 ht.put(key, obj); 73 } 74 public Shape getShape(String key) 75 { 76 Shape temp=ht.get(key); 77 return (Shape) temp.clone(); 78 } 79 } 80 81 public class ProtoTypeShape 82 { 83 public static void main(String[] args) { 84 ProtoTypeManager pm=new ProtoTypeManager(); 85 Shape obj1=(Circle)pm.getShape("Circle"); 86 obj1.countArea(); 87 Shape obj2=(Square)pm.getShape("Square"); 88 obj2.countArea(); 89 } 90 }
这是一个圆,请输入半径:2
该圆的面积=12.56
这是一个正方形,请输入它的边长:2
该正方形的面积=4