设计模式——原型模式

设计模式——原型模式

在这里插入图片描述
原型模式(Prototype),其实就是从一个对象再创建另外一个可定制的对象,而且不需知道任何创建的细节。

 abstract class Prototype
    {
        private string id;

        public Prototype(string id)
        {
            this.id = id;
        }

        public string Id
        {
            get { return id; }
        }

        public abstract Prototype Clone();
    }


    class ConcretePrototype1 : Prototype
    {

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

        }
        public override Prototype Clone()
        {

            //创建当前对象的浅表副本。方法是创建一个新对象,
            //然后将当前对象的非静态字段复制到该对象。如果字段是值类型,
            //则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;
            //因此,原始对象及其副本引用同一对象
            return (Prototype)this.MemberwiseClone();
        }
    }
         static void Main(string[] args)
        {
            ConcretePrototype1 p1 = new ConcretePrototype1("I");
            ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
            Console.WriteLine("Cloned:{0}", c1.Id);
        }

MemberwiseClone()方法是这样,如果字段是值类型的,则对字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象;因此对象及其复本引用同一对象

浅复制

 class WorkExperience
    {
        private string workData;
        public string WorkData
        {
            get { return workData; }
            set { workData = 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;


        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.WorkData = workDate;
            work.Company = company;   //调用此方法时,给对象的两属性赋值
        }
        //显示
        public void Display()
        {
            Console.WriteLine("{0} {1} {2}", name, sex, age);
            Console.WriteLine("工作经历{0} {1}", work.WorkData, work.Company); //显示时,显示“工作经历”的两属性的值
        }

        public object Clone()
        {
            return (Object)this.MemberwiseClone();
        }
    }
        static void Main(string[] args)
        {
            Resume a = new Resume("大鸟");
            a.SetPersonalInfo("男", "29");
            a.SetWorkExperience("1998-2000", "xxxx公司");

            Resume b = (Resume)a.Clone();                  //b和c都克隆于a,但当它们都设置了“工作经历”时,
            b.SetWorkExperience("1998-2006", "YYY公司");   //我们希望的结果是三个的显示不一样

            Resume c = (Resume)a.Clone();
            c.SetWorkExperience("1998-2002", "ZZZ公司");

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

深复制

 class WorkExperience : ICloneable //让“工作经历” 实现ICloneable接口
    {
        private string workData;
        public string WorkData
        {
            get { return workData; }
            set { workData = value; }
        }

        private string company;

        public string Company
        {
            get { return company; }
            set { company = value; }
        }


        //“工作经历”类实现克隆方法
        public Object Clone()
        {
            return (Object)this.MemberwiseClone();
        }
    }

    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.WorkData = workDate;
            work.Company = company;
        }

        //显示
        public void Display()
        {
            Console.WriteLine("{0} {1} {2}", name, sex, age);
            Console.WriteLine("工作经历{0} {1}", work.WorkData, 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;
        }
    }
            static void Main(string[] args)
        {
            Resume a = new Resume("大鸟");
            a.SetPersonalInfo("男", "29");
            a.SetWorkExperience("1998-2000", "xxxx公司");

            Resume b = (Resume)a.Clone();                  //b和c都克隆于a,但当它们都设置了“工作经历”时,
            b.SetWorkExperience("1998-2006", "YYY公司");   //我们希望的结果是三个的显示不一样

            Resume c = (Resume)a.Clone();
            c.SetWorkExperience("1998-2002", "ZZZ公司");

            a.Display();
            b.Display();
            c.Display();
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值