C# 设计模式之原型模式(Prototype)

原创 2013年12月06日 13:31:19

1.简历复印

先用一个基本的简历类如下(注:本文示例均引用于《大话设计模式》)

using System;
using System.Collections.Generic;
using System.Text;

namespace Resume
{
    class Resume
    {
        private string name;
        private string sex;
        private string age;
        private string timeArea;
        private string company;

        public Resume(string name)
        {
            this.name=name;
        }

        public void SetPersonalInfo(string sex, string age)
        {
            this.sex = sex;
            this.age = age;
        }

        public void SetWorkExperience(string timeArea, string company)
        {
            this.timeArea = timeArea;
            this.company = company;
        }

        public void Diaplay()
        {
            Console.WriteLine("{0} {1} {2}", name, sex, age);
            Console.WriteLine("工作经历: {0} {1}", timeArea, company);
        }
    }
}
如果要复印多份简历,客户端代码如下:

   static void Main(string[] args)
        {
            Resume a = new Resume("大鸟");
            a.SetPersonalInfo("男", "29");
            a.SetWorkExperience("1998-2000", "XX公司");
            Resume b = a;
            Resume c = a;

            a.Diaplay();
            b.Diaplay();
            c.Diaplay();

            Console.Read();
        }

不过,此种方法传的是引用,而不是值,a,b,c其实还是同一份简历。


2.原型模式

我们可以用原型模式(Prototype),所謂原型模式,是指从一个对象创建另外一个可定制的对象,而且我们不需要知道任何创建的细节.

.NET在System命名空间中提供了ICloneable接口,这个接口中只有唯一一个方法Clone().我们只需要实现ICloneable这个接口即可实现原型模式.

WorkExperience类是"工作经历"原型类代码如下:

class WorkExperience:ICloneable
    {
        private string workDate;
        public string WorkDate
        {
            get { return workDate; }
            set { workDate = value; }
        }

        private string company;
        public string Company
        {
            get { return company; }
            set { company = value; }
        }

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



在简历类中用"this.work = (WorkExperience)work.Clone();"语句即可实现原型类的克隆.


3.浅复制和深复制:

       1) 浅复制

MemberwiseClone()方法引用的字段如果是值类型的,则对该字段进行逐位复制;如果字段是引用类型,则复制引用但不复制引用的对象.

即原始对象及其复本引用同一对象.

当不同的复本的引用值改变时,原始对象及所有复本的引用值都会改变.这就是浅复制.

2) 深复制

当我们希望不同的复本的引用值有所区别时,就要使用深复制.

深复制把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象.

如示例中复制简历时,工作经历就相当于一个引用对象.可以对简历类的Clone()方法做些改变.

如下所示,调用简历类中私有的构造方法,克隆工作经历,这样就实现了深复制.

 public object Clone()
        {
            Resume obj = new Resume(this.work);
            obj.name = this.name;
            obj.sex = this.sex;
            obj.age = this.age;
            return obj;
        }

完整代码如下所示:

using System;
using System.Collections.Generic;
using System.Text;

namespace Resume
{
    public class Resume: ICloneable
    {
        private string name;
        private string sex;
        private string age;

        private WorkExperience work;

        public Resume(string name)
        {
            this.name=name;
            work = new WorkExperience();
        }

        private Resume(WorkExperience work)
        {
            this.work = (WorkExperience)work.Clone();
        }

        public void SetPersonalInfo(string sex, string age)
        {
            this.sex = sex;
            this.age = age;
        }

        public void SetWorkExperience(string workDate, string company)
        {
            work.WorkDate = workDate;
            work.Company = company;
        }

        public void Diaplay()
        {
            Console.WriteLine("{0} {1} {2}", name, sex, age);
            Console.WriteLine("工作經歷: {0} {1}", work.WorkDate, work.Company);
        }

        public object Clone()
        {
            Resume obj = new Resume(this.work);
            obj.name = this.name;
            obj.sex = this.sex;
            obj.age = this.age;
            return obj;
        }

        static void Main(string[] args)
        {
            Resume a = new Resume("大鳥");
            a.SetPersonalInfo("男", "29");
            a.SetWorkExperience("1998-2000", "XX公司");

            Resume b = (Resume)a.Clone();
            b.SetWorkExperience("1998-2006", "YY企業");

            Resume c = (Resume)a.Clone();
            c.SetPersonalInfo("男", "24");
            c.SetWorkExperience("1998-2006", "ZZ企業");

            a.Diaplay();
            b.Diaplay();
            c.Diaplay();

            Console.Read();
        }
    }
}

相关文章推荐

C#设计模式之原型模式(Prototype Pattern)

一、引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这未免会增加创建类的复杂度和耗费更多的内存空间,因为...

设计模式一日一练:原型模式(Prototype)

原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。...
  • ynnmnm
  • ynnmnm
  • 2014年05月09日 00:52
  • 931

java设计模式5--原型模式(Prototype)

本文地址:http://www.cnblogs.com/archimedes/p/java-prototype-pattern.html,转载请注明源地址。 原型模式 用原型实例指定创建对...

java设计模式---Prototype Pattern---原型模式(复制建立对象)

在我们建立Something类的实例时,会使用下面的表达式:  new Something(); 利用new指定类名可以产生对象实例。但是在有些情况下不靠new来产生实例是方便和必要的: 1. ...
  • ydd326
  • ydd326
  • 2011年09月08日 16:40
  • 598

设计模式(2)-创建型-原型模式(Prototype)

意图: 用原型实例指定创建对象的种类,当需要重复地创建相似对象时,通过拷贝这些原型创建新的对象。 个人理解: 原型模式主要用于对象的复制,它的核心是就是原型类Prototype: 实现Clonea...

设计模式:原型模式(Prototype)

一、定义与结构原型模式属于对象创建模式,我们从名字即可看出该原型模式的思想就是将一个对象作为原型,其进行复制、克隆产生和类似的新对象。GOF给它的定义为:用原型实例指定创建对象的种类,并且通过拷贝这些...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C# 设计模式之原型模式(Prototype)
举报原因:
原因补充:

(最多只允许输入30个字)