动机
在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。
如何应对这种变化?如何向“客户程序(使用这些对象的程序)”隔离出“这些易变对象” ,从而使得“依赖这些易变对象的客户程序”不随着需求改变而改变?
意图
使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象
示意图
原型设计模式代码实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 原型模式
{
class Program
{
static void Main(string[] args)
{
Computer computer = new Computer();
computer.name = "Dell.X5124";
computer.age = 5;
computer.factory = new Factory() { name = "Dell" };
computer.factory.manage = new Manage(){ManageName = "Nick"};
Computer C1 = (computer as ICloneable).Clone() as Computer;
C1.name = "Dell.X2546";
C1.age = 6;
C1.factory.name = "Sam";
C1.factory.manage.ManageName = "jack";
Console.WriteLine(computer);
Console.WriteLine(C1);
Console.ReadLine();
}
}
public class Computer:ICloneable
{
public string name { get; set; }
public int age { get; set; }
public Factory factory { get; set; }
public object Clone()
{
//return this.MemberwiseClone();//浅复制
//以下实现深Copy
var _Instace = this.MemberwiseClone() as Computer;
_Instace.factory = (this.factory as ICloneable).Clone() as Factory;
return _Instace;
}
public override string ToString()
{
return string.Format("电脑名字{0},使用年限{1},工厂名字{2},工厂管理者{3}",this.name,this.age,this.factory.name,this.factory.manage.ManageName);
}
}
public class Factory:ICloneable
{
public string name { get; set; }
public Manage manage { get; set; }
public object Clone()//深Copy
{
var _Instace = base.MemberwiseClone() as Factory;
_Instace.manage = (this.manage as ICloneable).Clone() as Manage;
return _Instace;
}
}
public class Manage:ICloneable
{
public string ManageName { get; set; }
public object Clone()//浅Copy
{
return base.MemberwiseClone();
}
}
}
ICloneable和DataSet
ICloneable
public object Clone();
实现ICloneable接口,即可实现Prototype模式
DataSet
4lone():只复制结构,不复制数据à浅复制
Copy();复制结构,也复制数据à深复制
浅Copy与深Copy
如果一个对象是复合对象或者包含其他的对象,那么克隆对象的问题是仅仅复制对象本身,还是连同被引用的对象一起复制?
实现IClone接口的类基本上都采用浅复制的策略
MemberwiseClone():
值类型:逐位复制
引用类型:只复制引用(指针)但不复制引用的对象
深复制:把引用对象的变量,指向复制过的,新的对象,而不是原有的被引用的对象
实现要点
善用ICloneable接口
产品的创建和初始化在类的Clone方法中完成
浅复制与深复制的区别
需要深复制的场合需要开发人员根据需要实现
有些情况下Clone功能不容易实现,特别是遇到对象的循环引用时
功能
在运行时增加或删除产品:只要通过客户原型实例即可将新产品类型增加到系统中,例如组态软件中工具箱中的每个工具可以对应一个注册的原型对象,可以通过增加原形对象扩展工具箱。
很容易地创建复杂的对象:在图形编辑和组态等软件中,经常需要创建复杂的图元。这些图元是由简单图元组成的,采用原型模式可以很容易地将复杂图元作为一般图元来使用,使软件的工具箱具有自扩展功能
适用性
当一个系统应该独立于产品的创建、构成和表示时,可以使用原型模式。
在使用时,我们可以用一些原型对象来代替生成相应对象的工厂对象,并且可以使拷贝、粘贴等操作独立于需要复制的对象。
总结
Prototype模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些“易变类”拥有“稳定的接口”。
Prototype模式对于“如何创建易变类的实体对象”采用“原型克隆”的方法来做,它使得我们可以非常灵活地动态创建“拥有某些稳定接口”的新对象——所需工作仅仅是注册一个新的对象(即原型),然后在任何需要的地方不断地Clone。
Prototype模式中的Clone方法可以利用.NET中的Object类的MemberwiseClone()方法或者序列化来实现深拷贝。
来源:oschina
链接:https://my.oschina.net/u/2874878/blog/735702