首页 > 其他 > 详细

原型模式

时间:2020-05-21 22:41:18      阅读:60      评论:0      收藏:0      [点我收藏+]

原型模式的定义是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。举个例子,我们有一个复杂对象,它内部有很多属性,它的构建过程也可能比较复杂。但是我们有一个场景,我们需要很多个这种对象来进行实验,我们可能需要观察它的某个属性的差异对实验结果的影响,那么我们怎么去实例化这些对象呢。传统的方式使用new来实例化,但是这样会非常麻烦,这个时候我们就可以使用原型模式。

我们先将该对象实例化一个实例出来。按照原型模式的定义,用原型实例指定创建对象的种类,然后拷贝这个对象。那么我们就将这个实例化出来的对象作为原型,然后我们通过拷贝这个原型来获得多个实例,之后我们只需要修改其中有差异的地方就可以了,这样就大大简化了我们实例化的过程。原型模式的结构图如下:

技术分享图片

 

 可以看到Prototype是一个原型,我们在需要对象的时候可以直接使用它的clone()方式来克隆一个实例。所以可以看出原型模式的核心就是实现实例的克隆,在C#中我们只需要实现一个ICloneable接口就可以达到我们的目的。

例如我们有一个简历对象

技术分享图片
    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();
        }

        //设置个人信息
        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 Display()
        {
            Console.WriteLine("{0} {1} {2}", name, sex, age);
            Console.WriteLine("工作经历:{0} {1}", work.WorkDate, work.Company);
        }

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

    }
View Code

 

 它里面包含了基本信息和工作经历,工作经历的定义如下

技术分享图片
    class WorkExperience
    {
        public string WorkDate { get; set; }
        public string Company { get; set; }
    }
View Code

 

按照原型模式的说法,我们就应该可以创建实例了

技术分享图片
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-2003", "ZZ企业");

    a.Display();
    b.Display();
    c.Display();

    Console.Read();
}    
View Code

 

那么输出结果是什么呢

技术分享图片

 

 

 是的,很奇怪,他们三个的工作经历都是一样的,并且都是最后设置的值。这个时候我们将他们各自工作经历的hashcode打出来

技术分享图片
public void Display()
{
    Console.WriteLine("{0} {1} {2} ", name, sex, age);
    Console.WriteLine("工作经历:{0} {1} HashCode:{2}", work.WorkDate, work.Company, work.GetHashCode());
}
View Code

 

那么这个时候显示的结果是什么呢

技术分享图片

 

 

 是的,他们的HashCode都是一样的,这说明在克隆的时候其实我们只是克隆它的引用,并没有将这个实际对象克隆,所以我们在修改克隆后对象时也会影响到原来的对象,这是原型模式需要特别注意的地方。知道了原因,那么我们就就它进行修改,我们的工作经历也要实现ICloneable接口

技术分享图片
class WorkExperience : ICloneable
{
    public string WorkDate { get; set; }

    public string Company { get; set; }

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

 

 然后我们也需要显示的调用一下工作经历的克隆方法来确保我们克隆不是它的引用

技术分享图片
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();
    }

    //设置个人信息
    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 Display()
    {
        Console.WriteLine("{0} {1} {2}", name, sex, age);
        Console.WriteLine("工作经历:{0} {1}", work.WorkDate, work.Company);
    }

    public Object Clone()
    {
        Resume obj = (Resume)this.MemberwiseClone();
        obj.work = (WorkExperience)work.Clone();    // 需要调用进行克隆

        return obj;
     }
}                
View Code

 

这个时候它的结果就是正常的了

技术分享图片

 

 

 几句官方的话,它主要适用于

  • 当要实例化的类是在运行时刻指定时,例如,通过动态装载
  • 为了避免创建一个与产品类层次平行工厂类
  • 当一个实例只能有几个不同状态组合中的一种时。建立对应数目的原型并克隆他们可能比每次都进行手工实例化更加方便。

原型模式

原文:https://www.cnblogs.com/aohost/p/12933917.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!