设计模式学习笔记之原型模式

来源:互联网 发布:挂课软件 编辑:程序博客网 时间:2024/05/01 01:37

存在目地:通过一个原型实例来指明所要创建的对象类型,并且用拷贝这个原型实例的办法创建出更多的同类型实例对象。

应用实例:细胞分裂,孙大圣的三根汗毛……

应用场合:避免创建一个与产品类层次平行的工厂类层次

简单实现:

using System;

// 抽象原型角色,具体原型角色的接口

abstract class Prototype

{

  // Fields

  private string id;

  // Constructors

  public Prototype( string id )

  {

    this.id = id;

  }

  public string Id

  {

    get{ return id; }

  }

  // Methods

  abstract public Prototype Clone();

}

// 具体原型1,实际被复制的对象

class ConcretePrototype1 : Prototype

{

  // Constructors

  public ConcretePrototype1( string id ) : base ( id ) {}

  // Methods

  override public Prototype Clone()

  {

    // 实现浅拷贝(当对象的字段值被拷贝时,字段引用的对象不会被拷贝)

    return (Prototype)this.MemberwiseClone();

  }

}

// 具体原型2

class ConcretePrototype2 : Prototype

{

  // Constructors

  public ConcretePrototype2( string id ) : base ( id ) {}

  // Methods

  override public Prototype Clone()

  {

    // Shallow copy

    return (Prototype)this.MemberwiseClone();

  }

}

// 客户端调用

class Client

{

  public static void Main( string[] args )

  {

    // 创建具体原型实例p1

ConcretePrototype1 p1 = new ConcretePrototype1( "I" );

// 克隆p1创建实例c1

    ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();

    Console.WriteLine( "Cloned: {0}", c1.Id );

 

    ConcretePrototype2 p2 = new ConcretePrototype2( "II" );

    ConcretePrototype2 c2 = (ConcretePrototype2)p2.Clone();

    Console.WriteLine( "Cloned: {0}", c2.Id );

  }

}

引入原型模式的本质在于利用已有的一个原型对象,快速的生成和原型对象一样的实例。注意Object类包括了MemberwiseClone()方法,这个方法被所有的对象继承。

带原型管理器的实现方式:

// 在原型管理器中存储用户预先定义的颜色原型,客户通过原型管理器克隆颜色对象

using System;

using System.Collections;

// 抽象原型角色

abstract class ColorPrototype

{

  // Methods

  public abstract ColorPrototype Clone();

}

//具体原型

class Color : ColorPrototype

{

  // Fields

  private int red, green, blue;

  // Constructors

  public Color( int red, int green, int blue)

  {

    this.red = red;

    this.green = green;

    this.blue = blue;

  }

  // Methods

  public override ColorPrototype Clone()

  {

    // Creates a 'shallow copy'

    return (ColorPrototype) this.MemberwiseClone();

  }

  public void Display()

  {

    Console.WriteLine( "RGB values are: {0},{1},{2}",

      red, green, blue );

  }

}

// 原型管理器角色,创建具体原型类的对象,并记录每一个被创建的对象。

class ColorManager

{

  // Fields

  Hashtable colors = new Hashtable();

  // Indexers

  public ColorPrototype this[ string name ]

  {

    get{ return (ColorPrototype)colors[ name ]; }

    set{ colors.Add( name, value ); }

  }

}

//// <summary>

///  PrototypeApp test

/// </summary>

class PrototypeApp

{

  public static void Main( string[] args )

  {

    ColorManager colormanager = new ColorManager();

 

    // Initialize with standard colors

    colormanager[ "red" ] = new Color( 255, 0, 0 );

    colormanager[ "green" ] = new Color( 0, 255, 0 );

    colormanager[ "blue" ] = new Color( 0, 0, 255 );

    // User adds personalized colors

    colormanager[ "angry" ] = new Color( 255, 54, 0 );

    colormanager[ "peace" ] = new Color( 128, 211, 128 );

    colormanager[ "flame" ] = new Color( 211, 34, 20 );

 

    // User uses selected colors

    string colorName = "red";

    Color c1 = (Color)colormanager[ colorName ].Clone();

    c1.Display();

    colorName = "peace";

    Color c2 = (Color)colormanager[ colorName ].Clone();

    c2.Display();

    colorName = "flame";

    Color c3 = (Color)colormanager[ colorName ].Clone();

    c3.Display();

  }

}

深拷贝实现:

using System;

class DeepCopy : ICloneable

{

  public int[] v = {1,2,3};

  // 默认构造函数

  public DeepCopy()

  {

  }

  // Clone方法调用的私有构造函数

  private DeepCopy(int[] v)

  {

    this.v = (int[])v.Clone();

  }

  public Object Clone()

  {

    // 构造一个新的DeepCopy对象,构造参数为原有对象中使用的 v

    return new DeepCopy(this.v);

  }

  public void Display()

  {

    foreach(int i in v)

    {  Console.Write( i + ", "); }

    Console.WriteLine();

  }

}

 

class Client

{

  public static void Main()

  {

    DeepCopy dc1 = new DeepCopy();

    DeepCopy dc2 = (DeepCopy)dc1.Clone();

    dc1.v[0] = 9;

    dc1.Display();

    dc2.Display();

  }

}

浅拷贝是指当对象的字段值被拷贝时,字段引用的对象不会被拷贝。例如,如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个浅拷贝,那么两个对象将引用同一个字符串。而深拷贝是对对象实例中字段引用的对象也进行拷贝的一种方式,所以如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个深拷贝的话,我们将创建一个新的对象和一个新的字符串--新对象将引用新字符串。需要注意的是执行深拷贝后,原来的对象和新创建的对象不会共享任何东西;改变一个对象对另外一个对象没有任何影响。

 

 

 

 

 

参考资料:

TerryLee's Tech Space

吕震宇博客

Erich Gamma《设计模式可复用面向对象软件的基础》 

原创粉丝点击