【原型模式】简历复印

举报
Laura_张 发表于 2022/08/26 22:46:17 2022/08/26
【摘要】 文章目录 原型模式原型模式:结构图:代码: 简历的原型实现结构图代码: 浅复制和深复制结构图:代码浅复制:深复制: 原型模式 针对简历的复印,并不...


原型模式

针对简历的复印,并不简单地复制黏贴,如果有需要改动的地方,那么就需要改动很多的地方。

原型模式:

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。

结构图:

在这里插入图片描述

代码:

原型类:

 abstract class Prototype
    {
        private string id;
        
        public Prototype (string id)
        {
            this.id = id;
        }
        public string Id
        {
            //获取内容
            get { return id; }
        }
        /// <summary>
        /// 抽象类的关键就是有这样一个Clone方法
        /// </summary>
        /// <returns></returns>
        public abstract Prototype Clone();
    }

具体原型类

 class ConcretePrototype1:Prototype 
    {
        public ConcretePrototype1(string id):base(id)
        {

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

客户端代码

   class Program
    {
        static void Main(string[] args)
        {
            ConcretePrototype1 p1 = new ConcretePrototype1("I");
            //克隆类ConcretePrototype1的对象,p1就能得到新的实例c1
            ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
            Console.WriteLine("Cloned:{0}", c1.Id);

            Console.Read();         
        }
    }

简历的原型实现

一般在初始化的信息不发生变化的情况下表,克隆是最好的方法,这既隐藏了对象创建的细节,又对性能大大的提高,它等于是不用重新初始化对象,而是动态地获得对象运行时的状态。

结构图

在这里插入图片描述

代码:

简历类:

//简历
    class Resume:ICloneable
    {
        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 Display()
        {
            Console.WriteLine("{0}  {1}  {2}", name, sex, age);
            //实现接口的方法,用来克隆方法
            Console.WriteLine("工作经历:{0}  {1} ", timeArea, company);
        }
        public Object Clone()
        {
            return (object)this.MemberwiseClone();
        }
    }

客户端代码

 class Program
    {
        static void Main(string[] args)
        {
            Resume a = new Resume("大鸟");
            a.SetPersonalInfo("男", "29");
            a.SetWorkExperience("1998-2000", "XX公司");
            
			//只需要调用Clone方法就可以实现新简历的生成,并且可以再修改新简历的细节
            Resume b = (Resume)a.Clone();
            b.SetWorkExperience("1998-2006", "XX企业");

            Resume c = (Resume)a.Clone();
            c.SetPersonalInfo("男", "24");

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

            Console.Read();
        }
    }

浅复制和深复制

MemberwiseClone()方法的使用:如果字段是值类型的,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象,因此,原始对象及其复本引用同一对象。

结构图:

浅复制:
在这里插入图片描述
深复制:
在这里插入图片描述

代码

浅复制:

工作经历类

   /// <summary>
    /// 工作经历
    /// </summary>
    class WorkExperience
    {
        private string workDate;
        public string WorkDate
        {
            get { return workDate; }
            set { workDate = value; }
        }
        private string company;
        public string Company
        {
            get { return company; }
            set { company = value; }
        }
    }

简历类

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

        //引用“工作经历”对象
        //work是引用类型
        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();
        }
    }

客户端代码

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

            //b和c都克隆于a,但当他们都设置了“工作经历”时,我们希望的结果是三个的显示不一样。
            //但是结果是三个结果是一样的,这里是应用了浅复制,对比一下深复制。
            Resume b = (Resume)a.Clone();
            b.SetWorkExperience("1998-2000", "YY公司");

            Resume c = (Resume)a.Clone();
            c.SetPersonalInfo("男", "24");
            c.SetWorkExperience("199-2000", "ZZ公司");

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

            Console.Read();
        }
    }

深复制:

工作经历

 /// <summary>
    /// 工作经历
    /// </summary>
    /// 让工作经历类实现ICloneable接口
    class WorkExperience :ICloneable 
    {
        private string workDate;
        private string WorkDate
        {
            get { return workDate; }
            set { workDate = value; }
        }
        private string company;
        public string Company
        {
            get { return company; }
            set { company = value; }

        }
        /// <summary>
        /// 让工作经历类实现克隆方法
        /// </summary>
        /// <returns></returns>
        public Object Clone()
        {
            return (Object)this.MemberwiseClone();
        }
    }

简历类

     /// <summary>
    /// 简历类
    /// </summary>
    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 )
        {
            //提供Clone方法调用的私有构造函数,以便克隆“工作经历”的数据
            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 Display()
        {
            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;
        }
    }

浅表复制,对于值类型,没有问题,但是对于引用类型,只是复制了引用,对引用的对象还是指向了原来的对象,所以,上面的给abc三个引用设置了不同的工作经历,但是却同时看到了三个引用都是最后一次的设置,这是因为这三个引用都指向了同一个对象。这个是浅复制。(被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。)

如果我们的需求是把要复制的对象所引用的对象都复制一遍,那么就是用深复制,深复制就是把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。

涉及深复制或者浅复制,数据集对象DataSet,它就有Clone()方法和Copy()方法,clone()方法用来复制DataSet的结果,但不复制DataSet的数据,实现了原型模式的浅复制,copy方法不但复制结构也复制数据,实现了原型模式的深复制。

编程是一门技术,大批量的改动,是一件非常丑陋的做法。

文章来源: blog.csdn.net,作者:张艳伟_Laura,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/Laura__zhang/article/details/123465230

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。