看设计模式看到了原型模式,居然还有这个模式啊!最近学的真的是到处都有模式的影子啊!到底什么是原型模式呢?原型,原型,顾名思义,不就是好多东西他们共同的主题部分不变,而细节也无需知道,这应该就是一个原型模式吧!定义为:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
结构图:
克隆对于我们是一个很常见的名词,也是设计模式中常用的,所以.NET在System命名空间中提供了ICLoneable接口,其中就是一个唯一的方法Clone(),所以我们只需要实现这个接口就可以完成原型模式了!
写着写着突然想起小时候写作业的场景了--摘抄词语多少多少遍……,当时使用的最快的方法就是用两个笔同时进行,这样就可以同时写两遍,还有就是耍小聪明,看一下同学们的,以最快的办法完成老师的需求。这不就是一个很好的原型模式吗?拿看同学的作业为例:
我们可以在此用ICloneable接口
客户端代码:
static void Main(string[] args)
{
Homework H = new Homework("参考的科目");
H.ArrangeHomework("语文");
H.ChoseColor("Blue");
Homework U = (Homework)H.Clone(); //调用Clone方法实现其他科目的生成
U.ArrangeHomework("数学");
H.Display();
U.Display();
Console.Read();
照葫芦画瓢,参考作业除了答案相同之外,其他的都可以相同或者不同的,对于上文对象里的数据都是string (一种拥有值类型特点的特殊引用类型), MemberwiseClone()方法就是这样。
值类型 | 对该字段执行逐位复制 |
引用类型 | 复制引用但不复制引用的对象 |
1)浅复制:被复制的对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。
新增加了一个选择方式的类,目的就是想要实现各种不一样的方式,来完成各种不同的作业。可是事实并非如此
客户端代码:
static void Main(string[] args)
{
Homework H = new Homework("参考的科目");
H.ArrangeHomework("语文");
H.ChoseColor("Blue", "楷体");
//U和I 都克隆于H
Homework U = (Homework)H.Clone(); //调用Clone方法实现其他科目的生成
U.ArrangeHomework("数学");
Homework I = (Homework)H.Clone();
I.ArrangeHomework("英语");
I.ChoseColor("Black", "行楷"); //对于选择的写作业的方式
H.Display();
U.Display();
I.Display();
Console.Read();
}
新增加的类:
class Pattern //选择笔的颜色,字体类型
{
private string color;
public string Color
{
get { return color; }
set { color = value; }
}
private string form;
public string Form
{
get { return form; }
set { form = value; }
}
}
调用:
class Homework:ICloneable
{
private string name;
private string kind;
private Pattern chose; //引用Pattern对象
public Homework (string name)
{
this.name = name; //在“作业类”实例化时,同时实例化“选择”类型
chose = new Pattern();
}
//整理个人作业
public void ArrangeHomework(string kind)
{
this.kind = kind;
}
//选择笔的颜色
public void ChoseColor(string color, string form)
{
chose.Color = color; //调用此方法,给对象的两属性赋值
chose.Form = form;
}
//显示
public void Display()
{
Console.WriteLine("{0} {1}", name, kind);
Console.WriteLine("笔的颜色: {0} {1}", chose .Color ,chose .Form ); //显示两属性的值
}
public Object Clone()
{
return (Object)this.MemberwiseClone();
}
}
出现的结果:
如此一来只是自己选择的科目不一样了,还是使用的一样的颜色,一样的字体类型。对于随后的两种选择,并未调用Pattern构造函数。而是进行的单纯的复制功能。
2)深复制
要想每写一科作业都有不一样的效果的话,也就是把引用对象的变量指向复制过的新对象,而并不是原有的被引用的对象,也就是深复制。
class Pattern : ICloneable //选择笔的颜色,字体类型,实现ICloneable接口
{
private string color;
public string Color
{
get { return color; }
set { color = value; }
}
private string form;
public string Form
{
get { return form; }
set { form = value; }
}
public Object Clone() //“类型”类实现克隆方法
{
return (Object)this.MemberwiseClone();
}
}
class Homework : ICloneable
{
private string name;
private string kind;
private Pattern chose; //引用Pattern对象
public Homework(string name)
{
this.name = name; //在“作业类”实例化时,同时实例化“选择”类型
chose = new Pattern();
}
private Homework (Pattern chose) //提供Clone方法调用的私有构造函数,以便克隆“类型”类的数据
{
this.chose = (Pattern)chose.Clone();
}
显示结果:
在原有的基础上进行稍微的改变得到自己想要的结果。