zoukankan      html  css  js  c++  java
  • 原型模式

    原型模式就是从一个对象再创建另一个可定制的对象,而不需要知道任何创建的细节。

    原型模式本身是比较简单的,不过其中牵涉到浅复制和深复制的实现,下面使用.Net自带的方法和接口分别实现浅复制和深复制:

        public class WorkExperience : ICloneable
        {
            public string workDate;
            public string experience;
    
            #region ICloneable 成员
    
            public object Clone()
            {
                //浅复制
                return this.MemberwiseClone();
            }
    
            #endregion
        }
    

      

    MemberwiseClone方法实现的是浅复制,即如果字段是值类型,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象,因此,原是对象及其复本引用的是同一对象。不过,经过测试发现,对string类型的执行的复制与值类型是相同的,修改新变量中string的值不会影响原变量的值测试如下:

    WorkExperience we = new WorkExperience();
    we.workDate="today";
    we.experience="test";
    //输出为work experience: today, test Console.WriteLine("work experience: {0},{1}", we.workDate, e.experience); WorkExperience we2 = (WorkExperience)we.Clone(); we2.experience = "test2"; we2.workDate = "tomorrow";
    //输出为work experience: tomorrow,test2 Console.WriteLine("work experience: {0},{1}", we2.workDate, e2.experience);
    //输出为work experience: today, test
    Console.WriteLine("work experience: {0},{1}", we.workDate, we.experience);

      

    下面演示如何进行深复制和浅复制:

        public class Resume : ICloneable
        {
            public string name;
         //引用类型,需要区分深复制和浅复制 public WorkExperience workExperience; public Resume(string name) { this.name = name; workExperience = new WorkExperience(); } public void SetExperience(string workDate, string experience) { workExperience.workDate=workDate; workExperience.experience=experience; } public void Show() { Console.WriteLine("name : {0}",name); Console.WriteLine("work experience: {0},{1}",workExperience.workDate,workExperience.experience); } /// <summary> /// 提供一个私有构造函数,供复制方法使用,以便复制WorkExperience的数据 /// </summary> /// <param name="workExperience"></param> private Resume(WorkExperience workExperience) { this.workExperience = (WorkExperience)workExperience.Clone(); } #region ICloneable 成员 /// <summary> ///深复制,实例化一个新的对象 /// </summary> /// <returns></returns> public object Clone() { Resume newResume = new Resume(this.workExperience); newResume.name = this.name; return newResume; } /// <summary> /// 浅复制 /// </summary> /// <returns></returns> public object Copy() { return this.MemberwiseClone(); } #endregion }

     上例中Clone和Copy分别实现了深复制和浅复制,测试如下:

    Resume myResume = new Resume("Kelly");
    myResume.SetExperience("2004-2008", "University");
    myResume.Show();


    //使用浅复制,更改WorkExperience,则被复制对象也被更改
    Resume newResume = (Resume)myResume.Copy();
    newResume.SetExperience("2008-2012", "Master Degree");
    newResume.name = "Mike";
    myResume.Show();

    //使用深复制,更改WorkExperience,被复制对象不会被更改
    Resume newResume2 = (Resume)myResume.Clone();
    newResume2.SetExperience("2012-now", "Company");
    newResume2.name = "Jack";
    myResume.Show();

      运行结果为:

    name : Kelly
    work experience: 2004-2008,University
    name : Kelly
    work experience: 2008-2012,Master Degree
    name : Kelly
    work experience: 2008-2012,Master Degree

    可以看出,name由于是string类型,所以始终不会被修改,work experience是引用类型,在第一次做浅复制后被修改,第二次做深复制后没有被修改。

    一般在初始化信息不发生变化的情况下,克隆是最好的办法,这即隐藏了对象创建的细节,又对性能有很大的提高。

  • 相关阅读:
    HDU 2122 HDU Today(dijkstra+map)
    DEDECMS后台传附件图片出现Upload filetype not allow解决办法
    织梦dedecms如何显示所有文章列表
    dedeCMS标签调用技巧和大全
    dedecms二次开发总结 变量参数
    dedecms上传图片相对路径改成绝对路径方法
    织梦Dedecms网站后台无法上传图片的步骤详解
    dedecms列表页调用当前文档的tags并带链接
    dedecms 自动获取缩略图
    dedecms网站转移(更换空间转移数据方法)
  • 原文地址:https://www.cnblogs.com/angela217/p/5405031.html
Copyright © 2011-2022 走看看