原型模式(ProtoType)

       原型模式(ProtoType):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。字面理解其意思就是从一个对象创建另外一个可定制的对象,而无需知道任何创建的细节,并能提高创建的性能,说白了就是copy技术,把一个对象完整的copy出一份。

       原型模式UML类图:


       实现克隆方法时,调用了.NET中封装的方法MemberwiseClone()方法,该方法创建一个浅表副本,方法是创建一个新对象, 然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。

       对于.NET而言原型抽象类ProtoType是用不到的,因为克隆的实用性,.NET在System的命名空间中提供了ICloneable接口,其中包含唯一的一个方法clone(),这样只需要实现这个接口就可以完成原型模式了。

       原型模式的有效利用会使得项目的性能大大的提高,在所创建对象的初始化不发生变化的情况下,使用克隆技术可以大大减少构造函数的调用,对于一个比较复杂费时间的构造函数来说,使用原型模式的克隆技术可以节省大量的时间,这样便很大程度上提高了性能,同时克隆技术还隐藏了对象创建的细节。

       但是我们必须了解在使用原型模式时,通过实现.NET中封装的接口IConeable,调用MemberwiseClone()方法来完成,该方法完成的是“浅拷贝”,在不涉及拷贝引用的情况下,可以达到很好的效果,然而,一旦涉及拷贝引用类型的深拷贝时,则不能达到想要的效果。

       首先,区分一下“浅拷贝”和“深拷贝”的区别,“浅拷贝”是指被复制的对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。而“深拷贝”则把引用对象的变量指向复制过的新对象。而不是原有被引用的原有对象。

       原型模式应用实例-简历的深复制实现:

(1)工作经历类

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

namespace ProtoType
{
    class WorkExperience :ICloneable
    {
        private string startDate;
        private string endDate;
        private string company;

        public string getStartDate()
        {
            return this.startDate;
        }
        public void setStartDate(string date)
        {
            this.startDate = date;
        }
        public string getEndDate()
        {
            return this.endDate;
        }
        public void setEndDate(string endDate)
        {
            this.endDate = endDate;
        }

        public string getCompany()
        {
            return this.company;
        }
        public void setCompany(string company)
        {
            this.company = company;
        }

        public Object Clone()
        {
            /*
             * MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,
             * 然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,
             * 则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制
             * 引用的对象;因此,原始对象及其复本引用同一对象。
             */
            return (Object)this.MemberwiseClone();
        }
    }
}
(2)简历类

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

namespace ProtoType
{
    class Resume : ICloneable
    {
        private string name;
        private string sex;
        private int age;
        private WorkExperience workExperience;

        public Resume(String name)
        {
            this.name = name;
            this.workExperience = new WorkExperience();
        }
        public Resume(WorkExperience we)
        {
            this.workExperience = new WorkExperience();
            this.workExperience.setStartDate(((WorkExperience)workExperience.Clone()).getStartDate());
            this.workExperience.setEndDate(((WorkExperience)workExperience.Clone()).getEndDate());
            this.workExperience.setCompany(((WorkExperience)workExperience.Clone()).getCompany());
        }
        public string getName()
        {
            return this.name;
        }
        public void setName(string name)
        {
            this.name = name;
        }

        public string getSex()
        {
            return this.sex;
        }
        public void setSex(string sex)
        {
            this.sex = sex;
        }

        public int getAge()
        {
            return this.age;
        }
        public void setAge(int age)
        {
            this.age = age;
        }

        public WorkExperience getWorkExperience()
        {
            return this.workExperience;
        }
        public void setWorkExperience(string startDate,string endDate,string company)
        {
            this.workExperience.setStartDate(startDate);
            this.workExperience.setEndDate(endDate);
            this.workExperience.setCompany(company);
        }

        public void display()
        {
            Console.WriteLine("{0} {1} {2}",this.name,this.sex,this.age);
            Console.WriteLine("工作经历:{0}-{1} {2}",this.workExperience.getStartDate(),
            this.workExperience.getEndDate(),this.workExperience.getCompany());
        }

        public Object Clone()
        {
            Resume resume = new Resume(this.workExperience);
            resume.setName(this.name);
            resume.setAge(this.age);
            resume.setSex(this.sex);
            return resume;        
            //return (Object)this.MemberwiseClone();
        }
    }
}
(3)客户端

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

namespace ProtoType
{
    class Program
    {
        static void Main(string[] args)
        {
            Resume re = new Resume("Lucy");
            re.setSex("女");
            re.setAge(20);
            re.setWorkExperience("2010","2012","百度");
          

            Resume re2 = (Resume)re.Clone();
            re2.setWorkExperience("2010","2012","谷歌");
           
           
            Resume re3 = (Resume)re.Clone();
            re3.setWorkExperience("2010", "2012", "微软");
            re.display();
            re2.display();
            re3.display();
            Console.Read();
        }
    }
}
(4)运行结果





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值