原型模式(Prototype Pattern)
1、概述
在软件系统中,有时候面临的产品类是动态变化的,而且这个产品类具有一定的等级结构。这时如果用工厂模式,则与产品类等级结构平行的工厂方法类也要随着这种变化而变化,显然不大合适。那么如何封装这种动态的变化?从而使依赖于这些易变对象的客户程序不随着产品类变化?
2、意图
原型模式是通过现有的一个对象,复制出更多的此类型的对象以供使用。
3、结构图
图解说明
UsePrototype类是用户类也是程序启动类
RGBColor类是一个颜色类
ColorPrototype类是抽象类,含有Clone方法
ConcretePrototype 类继承ColorPrototype,实现浅拷贝。
ConcretePrototypeDeep类继承ColorPrototype,实现深拷贝
关于深拷贝和浅拷贝简单的说:
浅拷贝(Shallow Copy影子克隆):只复制对象的基本类型。对象类型,仍属于原来的引用。
深拷贝(Deep Copy 深度克隆):不仅复制对象的基本类,同时也复制原对象中的对象.完全产生新对象。
4、代码的实现
注意:代码中的深拷贝是使用序列化实现的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
namespace PrototypePattern
{
[Serializable]
public abstract class ColorPrototype
{
public abstract ColorPrototype Clone();
}
[Serializable]
public class RGBColor
{
/// <summary>
/// 颜色的三色素:红、绿、兰
/// </summary>
private int _red,_green,_blue;
public RGBColor(int red, int green, int blue)
{
this._red = red;
this._green = green;
this._blue = blue;
}
public int RED
{
get
{
return this._red;
}
set
{
this._red = value;
}
}
public int GREEN
{
get
{
return this._green;
}
set
{
this._green = value;
}
}
public int BLUE
{
get
{
return this._blue;
}
set
{
this._blue = value;
}
}
}
/// <summary>
/// 实现浅拷贝
/// </summary>
public class ConcretePrototype :ColorPrototype
{
/// <summary>
/// 长、宽、高
/// </summary>
private int _lenth, _hign, _wide;
private RGBColor _color = null;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="length"></param>
/// <param name="hign"></param>
/// <param name="wide"></param>
public ConcretePrototype(int length, int hign, int wide,RGBColor color)
{
this._wide = wide;
this._lenth = length;
this._hign = hign;
this._color = color;
}
public void SetRectangle(int length, int hign, int wide)
{
this._lenth = length;
this._wide = wide;
this._hign = hign;
}
public RGBColor SGRGBColor
{
set
{
this._color = value;
}
get
{
return this._color;
}
}
/// <summary>
/// 浅拷贝,只复制对象的基本类型.对象类型,仍属于原来的引用.
/// </summary>
/// <returns></returns>
public override ColorPrototype Clone()
{
//创建当前ConcretePrototype的浅拷贝
return (ColorPrototype)this.MemberwiseClone();
}
/// <summary>
/// 将对象的信息显示出来
/// </summary>
public void Display()
{
//注意this._lenth, this._hign, this._wide是值类型
Console.WriteLine("This rectangle's area: ({0},{1},{2})", this._lenth, this._hign, this._wide);
//注意this._color是引用类型
Console.WriteLine("This rectangle's color: ({0},{1},{2})", this._color.RED,this._color.GREEN,this._color.BLUE);
}
}
/// <summary>
/// 深拷贝
/// </summary>
[Serializable]
public class ConcretePrototypeDeep : ColorPrototype
{
/// <summary>
/// 长、宽、高
/// </summary>
private int _lenth, _hign, _wide;
private RGBColor _color = null;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="length"></param>
/// <param name="hign"></param>
/// <param name="wide"></param>
public ConcretePrototypeDeep(int length, int hign, int wide, RGBColor color)
{
this._wide = wide;
this._lenth = length;
this._hign = hign;
this._color = color;
}
public void SetRectangle(int length, int hign, int wide)
{
this._lenth = length;
this._wide = wide;
this._hign = hign;
}
public RGBColor SGRGBColor
{
set
{
this._color = value;
}
get
{
return this._color;
}
}
/// <summary>
/// 深度拷贝,不仅复制对象的基本类,同时也复制原对象中的对象.完全产生新对象。
/// </summary>
/// <returns></returns>
public override ColorPrototype Clone()
{
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, this);
stream.Position = 0;
return (ColorPrototype)formatter.Deserialize(stream);
}
public void Display()
{
Console.WriteLine("This rectangle's area: ({0},{1},{2})", this._lenth, this._hign, this._wide);
Console.WriteLine("This rectangle's color: ({0},{1},{2})", this._color.RED,this._color.GREEN,this._color.BLUE);
}
}
public class UsePrototype
{
public static void Main(string[] args)
{
Console.WriteLine("====== ====== 浅拷贝 ====== ======");
ColorPrototype colorPrototype = new ConcretePrototype(100, 200, 300,new RGBColor(20,100,130));
Console.WriteLine("原对象信息为:");
((ConcretePrototype)colorPrototype).Display();
ColorPrototype colorPrototypeClone = colorPrototype.Clone();
((ConcretePrototype)colorPrototypeClone).SetRectangle(150, 250, 350);
((ConcretePrototype)colorPrototypeClone).SGRGBColor.RED = 30;
((ConcretePrototype)colorPrototypeClone).SGRGBColor.GREEN = 120;
((ConcretePrototype)colorPrototypeClone).SGRGBColor.BLUE = 100;
Console.WriteLine("拷贝对象信息改变后为:");
((ConcretePrototype)colorPrototypeClone).Display();
Console.WriteLine("只复制对象的基本类型.对象类型,仍属于原来的引用");
((ConcretePrototype)colorPrototype).Display();
Console.WriteLine("====== ====== 深拷贝 ====== ======");
colorPrototype = new ConcretePrototypeDeep(100, 200, 300, new RGBColor(20, 100, 130));
Console.WriteLine("原对象信息为:");
((ConcretePrototypeDeep)colorPrototype).Display();
colorPrototypeClone = colorPrototype.Clone();
((ConcretePrototypeDeep)colorPrototypeClone).SetRectangle(150, 250, 350);
((ConcretePrototypeDeep)colorPrototypeClone).SGRGBColor.RED = 30;
((ConcretePrototypeDeep)colorPrototypeClone).SGRGBColor.GREEN = 120;
((ConcretePrototypeDeep)colorPrototypeClone).SGRGBColor.BLUE = 100;
Console.WriteLine("拷贝对象信息改变后为:");
((ConcretePrototypeDeep)colorPrototypeClone).Display();
Console.WriteLine("不仅复制对象的基本类,同时也复制原对象中的对象.完全产生新对象。");
((ConcretePrototypeDeep)colorPrototype).Display();
}
}
}
5、运行结果
可以看出,浅拷贝中,拷贝对象中的引用对象(RGBColor类对象)与原对象中的对应的引用对象(RGBColor类对象)指向同一个内存地址,而值信息则拷贝对象有一个另外的拷贝。
深拷贝中值变量和引用变量都重新开辟了一个内存,所以拷贝对象与原对象中的变量间所在的内存不一样。
浙公网安备 33010602011771号