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

设计模式(创建型)之原型模式(Prototype Pattern)

要理解原型原型模式必须先理解Java里的浅复制和深复制。有的地方,复制也叫做克隆。Java提供这两种克隆方式。 因为Java中的提供clone()方法来实现对象的克隆,所以Prototype模式实现一...
  • yanbober
  • yanbober
  • 2015年04月29日 11:28
  • 2881

C++设计模式-Prototype原型模式

作用: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 Prototype模式提供了一个通过已存在对象进行新对象创建的接口(Clone), Clone()实现和具体的语言...
  • u010229420
  • u010229420
  • 2016年08月22日 16:00
  • 672

我所理解的设计模式(C++实现)——原型模式(Prototype Pattern)

解决的问题: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。这个其实和C++的拷贝构造函数的作用是一致的,实际上就是动态抽取当前对象运行时的状态。 类图结构:      ...
  • LCL_data
  • LCL_data
  • 2013年04月06日 16:01
  • 9248

软件设计模式——原型模式(Prototype)

定义与结构原型模式属于对象创建模式,我们从名字即可看出该原型模式的思想就是将一个对象作为原型,其进行复制、克隆产生和类似的新对象。GOF给它的定义为:用原型实例指定创建对象的种类,并且通过拷贝这些原型...
  • Jungle_hello
  • Jungle_hello
  • 2016年04月19日 16:43
  • 438

设计模式-原型模式-prototype-python

原型模型
  • CCyutaotao
  • CCyutaotao
  • 2017年08月03日 16:44
  • 298

Spring中原型prototype的准确使用

Spring中原型prototype的准确使用实际问题项目中,报表导出涉及到了在同一个类的两个不同方法中,都有相同的查询数据库的操作,一个方法是用于获取内容,一个是用于获取条数的,大概类似于这样:@S...
  • unifirst
  • unifirst
  • 2016年01月08日 17:04
  • 10974

Java技术_每天掌握一种设计模式(006)_使用场景及简单实例(创建型:原型模式)

模式描述 用原型实例指定创建对象的种类,并且通过拷贝来创建新的对象。 2.模式作用 可以一定程度上解耦,消费者和对象的构造过程隔离开,对象如何构造与消费者完全无关。 可以一定程度提升效率,复杂对...
  • ooppookid
  • ooppookid
  • 2015年01月20日 10:14
  • 2191

<六>读<<大话设计模式>>之原型模式

原型模式也是很简单的一种模式,对于java来说已经有相应的接口了(Cloneable)。关于原型模式>是以投放简历作为例子讲解的,即我要投放很多简历,其实每个简历都一样,所以只要我写好一份,其他的复制...
  • jzhf2012
  • jzhf2012
  • 2014年10月30日 20:58
  • 1047

Java设计模式——原型模式

原型模式是为了解决一些不必要的对象创建过程。当Java JDK中提供了Cloneable接口之后,原型模式就变得异常的简单了。虽然由于Cloneable的引入使用程序变得更简单了,不过还是有一些需要说...
  • u013761665
  • u013761665
  • 2016年03月03日 13:50
  • 1847

JAVA设计模式之原型模式

定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。 类型:创建类模式 类图: 原型模式主要用于对象的复制,它的核心是就是类图中的原型类Prototype。Prototype...
  • jason0539
  • jason0539
  • 2014年04月08日 08:22
  • 14840
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C# 设计模式之原型模式(Prototype)
举报原因:
原因补充:

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