Prototype模式被翻译为原型模式,这里我们看到了创建对象的另外一种方式。
一般在程序中我们可以使用的对象创建方法有:
1. 使用new关键字创建对象,这是最最普通的一种。
2. 使用对象序列化( Serialize)创建对象
3. 使用反射机制( Reflection)动态创建对象
4. 使用clone(克隆)方式创建对象
这里的Prototype模式用的就是第4种方法,它通过复制一个已经存在的对象实例来创建新的对象实例,被复制的对象实例称为“原型”。原型模式多应用在创建复杂的或者耗时的实例,因为在这种情况下通过复制一个已经存在的对象使得程序的运行效率更高;或者值相等而命名不一样的同类数据。
C#示例代码:
Java示例代码:
一般在程序中我们可以使用的对象创建方法有:
1. 使用new关键字创建对象,这是最最普通的一种。
2. 使用对象序列化( Serialize)创建对象
3. 使用反射机制( Reflection)动态创建对象
4. 使用clone(克隆)方式创建对象
这里的Prototype模式用的就是第4种方法,它通过复制一个已经存在的对象实例来创建新的对象实例,被复制的对象实例称为“原型”。原型模式多应用在创建复杂的或者耗时的实例,因为在这种情况下通过复制一个已经存在的对象使得程序的运行效率更高;或者值相等而命名不一样的同类数据。
C#示例代码:
public
enum
RecordType
{
Car,
Person
}
/// <summary>
/// Record is the Prototype
/// </summary>
public abstract class Record
{
public abstract Record Clone();
}
/// <summary>
/// PersonRecord is the Concrete Prototype
/// </summary>
public class PersonRecord : Record
{
string name;
int age;
public override Record Clone()
{
return (Record)this.MemberwiseClone(); // default shallow copy
}
}
/// <summary>
/// CarRecord is another Concrete Prototype
/// </summary>
public class CarRecord : Record
{
string carname;
Guid id;
public override Record Clone()
{
CarRecord clone = (CarRecord)this.MemberwiseClone(); // default shallow copy
clone.id = Guid.NewGuid(); // always generate new id
return clone;
}
}
/// <summary>
/// RecordFactory is the client
/// </summary>
public class RecordFactory
{
private static Dictionary<RecordType, Record> _prototypes =
new Dictionary<RecordType, Record>();
/// <summary>
/// Constructor
/// </summary>
public RecordFactory()
{
_prototypes.Add(RecordType.Car, new CarRecord());
_prototypes.Add(RecordType.Person, new PersonRecord());
}
/// <summary>
/// The Factory method
/// </summary>
public Record CreateRecord(RecordType type)
{
return _prototypes[type].Clone();
}
}
{
Car,
Person
}
/// <summary>
/// Record is the Prototype
/// </summary>
public abstract class Record
{
public abstract Record Clone();
}
/// <summary>
/// PersonRecord is the Concrete Prototype
/// </summary>
public class PersonRecord : Record
{
string name;
int age;
public override Record Clone()
{
return (Record)this.MemberwiseClone(); // default shallow copy
}
}
/// <summary>
/// CarRecord is another Concrete Prototype
/// </summary>
public class CarRecord : Record
{
string carname;
Guid id;
public override Record Clone()
{
CarRecord clone = (CarRecord)this.MemberwiseClone(); // default shallow copy
clone.id = Guid.NewGuid(); // always generate new id
return clone;
}
}
/// <summary>
/// RecordFactory is the client
/// </summary>
public class RecordFactory
{
private static Dictionary<RecordType, Record> _prototypes =
new Dictionary<RecordType, Record>();
/// <summary>
/// Constructor
/// </summary>
public RecordFactory()
{
_prototypes.Add(RecordType.Car, new CarRecord());
_prototypes.Add(RecordType.Person, new PersonRecord());
}
/// <summary>
/// The Factory method
/// </summary>
public Record CreateRecord(RecordType type)
{
return _prototypes[type].Clone();
}
}
MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。
例 如,考虑一个名为 X 的对象,该对象引用对象 A 和 B。对象 B 又引用对象 C。X 的浅表副本创建一个新对象 X2,该对象也引用对象 A 和 B。与此相对照,X 的深层副本创建一个新对象 X2,该对象引用新对象 A2 和 B2,它们分别是 A 和 B 的副本。B2 又引用新对象 C2,C2 是 C 的副本。使用实现 ICloneable 接口的类执行对象的浅表或深层复制。
Java示例代码:
/** Prototype Class **/
public class Cookie implements Cloneable {
public Object clone()
{
try{
//In an actual implementation of this pattern you would now attach references to
//the expensive to produce parts from the copies that are held inside the prototype.
return this.getClass().newInstance();
}
catch(InstantiationException e)
{
e.printStackTrace();
return null;
}
}
}
/** Concrete Prototypes to clone **/
public class CoconutCookie extends Cookie { }
/** Client Class**/
public class CookieMachine
{
private Cookie cookie;//could have been a private Cloneable cookie;
public CookieMachine(Cookie cookie) {
this.cookie = cookie;
}
public Cookie makeCookie() {
return (Cookie)cookie.clone();
}
public Object clone() { }
public static void main(String args[]){
Cookie tempCookie = null;
Cookie prot = new CoconutCookie();
CookieMachine cm = new CookieMachine(prot);
for(int i=0; i<100; i++)
tempCookie = cm.makeCookie();
}
}
public class Cookie implements Cloneable {
public Object clone()
{
try{
//In an actual implementation of this pattern you would now attach references to
//the expensive to produce parts from the copies that are held inside the prototype.
return this.getClass().newInstance();
}
catch(InstantiationException e)
{
e.printStackTrace();
return null;
}
}
}
/** Concrete Prototypes to clone **/
public class CoconutCookie extends Cookie { }
/** Client Class**/
public class CookieMachine
{
private Cookie cookie;//could have been a private Cloneable cookie;
public CookieMachine(Cookie cookie) {
this.cookie = cookie;
}
public Cookie makeCookie() {
return (Cookie)cookie.clone();
}
public Object clone() { }
public static void main(String args[]){
Cookie tempCookie = null;
Cookie prot = new CoconutCookie();
CookieMachine cm = new CookieMachine(prot);
for(int i=0; i<100; i++)
tempCookie = cm.makeCookie();
}
}