模式设计 创建型 Prototype

本文详细解释了C#中原型模式的概念、适用性及其实现方式,包括原型类的设计、克隆方法的使用及浅拷贝与深拷贝的区别。同时,文章深入探讨了原型模式的优点与缺点,帮助开发者更好地理解和应用这一设计模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


名称Prototype
结构o_prototype.bmp
意图用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
适用性
  • 当要实例化的类是在运行时刻指定时,例如,通过动态装载;或者
  • 为了避免创建一个与产品类层次平行的工厂类层次时;或者
  • 当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
  


Code Example
namespace Prototype_DesignPattern
{
    using System;

    // Objects which are to work as prototypes must be based on classes which 
    
// are derived from the abstract prototype class
    abstract class AbstractPrototype 
    {
        abstract public AbstractPrototype CloneYourself();
    }


    // This is a sample object
    class MyPrototype : AbstractPrototype 
    {
        override public AbstractPrototype CloneYourself()
        {
            return ((AbstractPrototype)MemberwiseClone());
        }

        // lots of other functions go here!
    }


    // This is the client piece of code which instantiate objects
    
// based on a prototype. 
    class Demo 
    {
        private AbstractPrototype internalPrototype;

        public void SetPrototype(AbstractPrototype thePrototype)
        {
            internalPrototype = thePrototype;            
        }


        public void SomeImportantOperation()
        {
            // During Some important operation, imagine we need
            
// to instantiate an object - but we do not know which. We use
            
// the predefined prototype object, and ask it to clone itself. 

            AbstractPrototype x;
            x = internalPrototype.CloneYourself();
            // now we have two instances of the class which as as a prototype
        }

    }


    /// <summary>
    
///    Summary description for Client.
    
/// </summary>

    public class Client
    {
        public static int Main(string[] args)
        {                        
            Demo demo = new Demo();
            MyPrototype clientPrototype = new MyPrototype();
            demo.SetPrototype(clientPrototype);
            demo.SomeImportantOperation();

            return 0;
        }

    }

}

C#对原型模式的支持

在C#里面,我们可以很容易的通过Clone()方法实现原型模式。任何类,只要想支持克隆,必须实现C#中的ICloneable接口。ICloneable接口中有一Clone方法,可以在类中复写实现自定义的克隆方法。克隆的实现方法有两种:浅拷贝(shallow copy)与深拷贝(deep copy)。
五、 浅拷贝与深拷贝

下面给出浅拷贝与深拷贝的两个例子,例子使用了ICloneable接口。C#中的数组是引用型的变量,我们通过数组来进行演示:

浅拷贝:

using System;

class ShallowCopy : ICloneable
{
  public int[] v = {1,2,3};

  public Object Clone()
  {
    return this.MemberwiseClone();
  }


  public void Display()
  {
    foreach(int i in v)
      Console.Write( i + ", ");
    Console.WriteLine();
  }

}


class Client
{
  public static void Main()
  {
    ShallowCopy sc1 = new ShallowCopy();
    ShallowCopy sc2 = (ShallowCopy)sc1.Clone();
    sc1.v[0] = 9;

    sc1.Display();
    sc2.Display();
  }

}


ShallowCopy对象实现了一个浅拷贝,因此当对sc1进行克隆时,其字段v并没有克隆,这导致sc1与sc2的字段v都指向了同一个v,因此,当修改了sc1的v[0]后,sc2的v[0]也发生了变化。

深拷贝:

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();
  }

}


这次在克隆的时候,不但克隆对象本身,连里面的数组字段一并克隆。因此,最终打印出来的dc1与dc2不同。


Prototype模式的优点与缺点 
Prototype模式的优点包括 

1、Prototype模式允许动态增加或减少产品类。由于创建产品类实例的方法是产批类内部具有的,因此增加新产品对整个结构没有影响。 

2、Prototype模式提供了简化的创建结构。工厂方法模式常常需要有一个与产品类等级结构相同的等级结构,而Prototype模式就不需要这样。 

3、Portotype模式具有给一个应用软件动态加载新功能的能力。由于Prototype的独立性较高,可以很容易动态加载新功能而不影响老系统。 

4、产品类不需要非得有任何事先确定的等级结构,因为Prototype模式适用于任何的等级结构。 


Prototype模式的缺点: 

Prototype模式的最主要缺点就是每一个类必须配备一个克隆方法。而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值