设计模式之原型模式

  今天学习了原型模式,在这里记下来:

  工作中,很多时候要复制一个方法,或什么的?如果直用CTRL_V,那样太麻烦了,还不能改,下面做一个浅复制的原型模式!

  代码如下:先定义一个类:

View Code
//定义一个个人简历类,继承ICloneable 这个接口,这个接口可以帮我们复制
    public 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;
        }

        /// <summary>
        /// 设置个人信息
        /// </summary>
        /// <param name="sex"></param>
        /// <param name="age"></param>
        public void Setpersonalinfo(string sex, string age)
        {
            this.sex = sex;
            this.age = age;
        }
        /// <summary>
        /// 设置工作经历
        /// </summary>
        /// <param name="timearea"></param>
        /// <param name="company"></param>
        public void SetWorkExperience(string timearea, string company)
        {
            this.timearea = timearea;
            this.company = company;
        }
        /// <summary>
        /// 显示
        /// </summary>
        public void Display()
        {
            Console.WriteLine("{0}  {1} {2}", name, sex, age);
            Console.WriteLine("工作经历:{0},{1}", timearea, company);
        }

        //实现ICloneable这个接口返回一个浅表副本
        public Object Clone()
        {
            return (Object)this.MemberwiseClone();
        }
    }

这个类定义完了之后,然后我们在控制台来调用,代码如下:

View Code
class Program
    {
        static void Main(string[] args)
        {
            //创建第一个对象
            Resume a= new Resume("小何");
            a.Setpersonalinfo("","25");
            a.SetWorkExperience("1999", "xxx公司");

            //创建第二个对象,浅复制第一个对象
            Resume b = (Resume)a.Clone();


            //创建第三个对象,浅复制第一个对象
            Resume c = (Resume)a.Clone();

            //再修改工作经历这个方法
            c.SetWorkExperience("1999-3000", "新浪公司");

            
            //输出这三个对象的结果
            a.Display();
            b.Display();
            c.Display();

            Console.ReadKey();
             
        }

        
    }

输出结果果如下:

这样就可以看得清清楚楚了,我们只创建了一个对象,然后可以直接复制这个对象,同时还可以做一些修改。

 这样以后写代码如果有这样的情况,就可以直接使用,原型模式了!方便强大!

   刚刚上面原型模式是一个浅复制的原型模式,我们都是复制类中的字符串属性,但如果这些属性是从外面类中传过来,

  这时,这个原型模式得到结果就是不是上面那样的,它得到的三个对象结果都会一样,都只是最后一个对象的结果同。

  为什么会这样呢,因为我们上面这个浅复制,如果是字符串值类型,是可以浅复制的,但如果是一个引用类型就会不一样了!

  那我们现在把刚才的代码改下,做一个深复制的原理模式!

  我们这次加一个工作经历类:我们在这个类中也继承ICloneable这个接口,然后重写这个接口!

  代码:

View Code
/// <summary>
    /// 工作经历类
    /// </summary>
    public 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; }
        }

        #region ICloneable 成员

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

        #endregion
    }

  这个类写完了以后,我们再写一个工作经历类,

代码

View Code
//定义一个个人简历类,继承ICloneable 这个接口,这个接口可以帮我们复制
    public class Resume : ICloneable
    {
        //定义一些个人信息
        private string name;
        private string sex;
        private string age;
        
        //声明一个工作经历类
        public WorkExperience work;
        
        //定义一个外部的构造函数
        public Resume(string name)
        {
            this.name = name;
            work = new WorkExperience();
        }

        //定义一个内部的构造函数,传一个工作经历类过来
        private Resume(WorkExperience work)
        {
            //提供Clone方法调用私有的构造函数,以便克隆“工作经历”的数据
            this.work = (WorkExperience)work.Clone();
        }
        /// <summary>
        /// 设置个人信息
        /// </summary>
        /// <param name="sex"></param>
        /// <param name="age"></param>
        public void Setpersonalinfo(string sex, string age)
        {
            this.sex = sex;
            this.age = age;
        }
        /// <summary>
        /// 设置工作经历
        /// </summary>
        /// <param name="timearea"></param>
        /// <param name="company"></param>
        public void SetWorkExperience(string timearea, string company)
        {
            work.Workdate = timearea;
            work.Company = company;
        }
        /// <summary>
        /// 显示
        /// </summary>
        public void Display()
        {
            Console.WriteLine("{0}  {1} {2}", name, sex, age);
            Console.WriteLine("工作经历:{0},{1}",work .Workdate ,work .Company );
        }

        //实现ICloneable这个接口
        public Object Clone()
        {
            //调用私有的构造方法,让“工作经历”克隆完成然后再给这个“简历”对象的相关字段赋值,最终返回一个深复制的简历对象
            Resume obj = new Resume(this.work );

            obj.name = this.name;
            obj.sex = this.sex;
            obj.age = this.age;
            return obj;
        }
    }

 然后在控制台调用

View Code
static void Main(string[] args)
        {
            //创建第一个对象
            Resume a= new Resume("小何");
            a.Setpersonalinfo("","25");
            a.SetWorkExperience("1999", "xxx公司");

            //创建第二个对象,浅复制第一个对象
            Resume b = (Resume)a.Clone();


            //创建第三个对象,浅复制第一个对象
            Resume c = (Resume)a.Clone();

            //再修改工作经历这个方法
            c.SetWorkExperience("1999-3000", "新浪公司");

            
            //输出这三个对象的结果
            a.Display();
            b.Display();
            c.Display();

            Console.ReadKey();
             
        }

 结果:

这样结果也是一样了,现在深复制原型模式和浅原型模式都做完了,以后哪种情况下都可以很好的用了!

原文地址:https://www.cnblogs.com/xu3593/p/3076034.html