首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >C#设计模式——(创建型-原型设计模式)

C#设计模式——(创建型-原型设计模式)

原创
作者头像
用户10053120
发布2022-10-09 11:06:28
发布2022-10-09 11:06:28
6570
举报
文章被收录于专栏:C# 设计原则C# 设计原则

一、应用场景

简历类中包含:姓名、性别、年龄、工作经验...

代码语言:javascript
复制
        public class Resume
        {
            public string Name { set; get; }
            public int Age { get; set; }
            public char Gender { get; set; }
            public string TimeArea { get; set; }
            public string Company { get; set; }
            public void SetInfo(string name,int age,char gender)
            {
                this.Name = name;
                this.Age = age;
                this.Gender = gender;
            }
            public void SetWorkExp(string timeArea,string company)
            {
                this.TimeArea = timeArea;
                this.Company = company;
            }
            public void ShowResume()
            {
                Console.WriteLine($"{this.Name}{this.Age}{this.Gender}");
                Console.WriteLine($"{this.TimeArea}{this.Company}");
            }
        }
代码语言:javascript
复制
//如果要创建重复的对象时,要重复写
            Resume resume = new Resume();
            resume.SetInfo("张三", 23, '男');
            resume.SetWorkExp("2012-2022", "tengxun");
            resume.ShowResume();
            Resume resume1 = new Resume();
            resume1.SetInfo("李四", 33, '男');
            resume1.SetWorkExp("2002-2022", "tengxun");
            resume1.ShowResume();

二、原型模式用于创建重复的对象,又能保证性能

代码语言:javascript
复制
        public abstract class ResumePrototype
        {
            public string Name { get; set; }
            public ResumePrototype(string name)
            {
                this.Name = name;
            }
            public abstract ResumePrototype Clone();
        }
        public class Resume1 : ResumePrototype
        {
            public Resume1(string name):base(name)
            {
            }
            public override ResumePrototype Clone()
            {
                //MemberwiseClone 浅克隆
                //将值类型成员全部复制一份并且搞一份新的
                //复制引用类型成员的引用,并不复制对象
                return (ResumePrototype)this.MemberwiseClone();
            }
        }
代码语言:javascript
复制
            Resume1 re = new Resume1("zhangsan");
            //通过Clone方法,复制的对象与复制一个引用是完全不同的
            Resume1 re1 = (Resume1)re.Clone();
            Console.WriteLine(re1.Name);
            Console.ReadKey();

三、简化的原型模式

代码语言:javascript
复制
         public class Resume2:ICloneable //1、实现接口
        {
            public string Name { set; get; }
            public int Age { get; set; }
            public char Gender { get; set; }
            public string TimeArea { get; set; }
            public string Company { get; set; }

            public object Clone()
            {
                return this.MemberwiseClone();//2、调用MemberwiseClone方法
            }

            public void SetInfo(string name, int age, char gender)
            {
                this.Name = name;
                this.Age = age;
                this.Gender = gender;
            }
            public void SetWorkExp(string timeArea, string company)
            {
                this.TimeArea = timeArea;
                this.Company = company;
            }
            public void ShowResume()
            {
                Console.WriteLine($"{this.Name}{this.Age}{this.Gender}");
                Console.WriteLine($"{this.TimeArea}{this.Company}");
            }
        }
代码语言:javascript
复制
            Resume2 res = new Resume2();
            res.SetInfo("孙权", 20, '男');
            res.SetWorkExp("2018-2022", "腾讯");
            Resume2 res1 = (Resume2)res.Clone();
            res.ShowResume();
            res1.ShowResume();

四、浅拷贝的问题

代码语言:javascript
复制
            Resume2 res = new Resume2();
            res.SetInfo("孙权", 20, '男');
            res.SetWorkExp("2018-2022", "腾讯");
            Resume2 res1 = (Resume2)res.Clone();
            Resume2 res2 = (Resume2)res.Clone();
            res2.SetWorkExp("2018-2022", "阿里");
            res.ShowResume();
            res1.ShowResume();
            res2 .ShowResume();//值类型,res2发生了变化;引用类型,全部发生变化
            
代码语言:javascript
复制
         public class Experience:ICloneable
        {
            public string TimeArea { get; set; }
            public string Company { get; set; }

            public object Clone()
            {
                return this.MemberwiseClone();
            }
        }
         public class Resume3 : ICloneable //1、实现接口
        {
            public string Name { set; get; }
            public int Age { get; set; }
            public char Gender { get; set; }
            public Experience Exp;//引用类型
            public object Clone()
            {
                return this.MemberwiseClone();//2、调用MemberwiseClone方法
            }
            public Resume3()
            {
                this.Exp = new Experience();
            }
            public void SetInfo(string name, int age, char gender)
            {
                this.Name = name;
                this.Age = age;
                this.Gender = gender;
            }
            public void SetWorkExp(string timeArea, string company)
            {
                this.Exp.TimeArea = timeArea;
                this.Exp.Company = company;
            }
            public void ShowResume()
            {
                Console.WriteLine($"{this.Name}{this.Age}{this.Gender}");
                Console.WriteLine($"{this.Exp.TimeArea}{this.Exp.Company}");
            }
        }

五、(伪)深拷贝

真正的深拷贝要用反射、序列化

代码语言:javascript
复制
        public class Resume3 : ICloneable //1、实现接口
        {
            public string Name { set; get; }
            public int Age { get; set; }
            public char Gender { get; set; }
            public Experience Exp;//引用类型
            public object Clone()
            {
                //如果还调用Resume2的MemberwiseClone,引用类型永远也不可能被复制一份新的
                //return this.MemberwiseClone();//2、调用MemberwiseClone方法

                //在创建新对象的时候,把工作经验这个引用类型也复制一份
                Resume3 resume3 = new Resume3(this.Exp);
                resume3.Name = this.Name;
                resume3.Age = this.Age;
                resume3.Gender = this.Gender;
                return resume3;
            }
            public Resume3()
            {
                this.Exp = new Experience();
            }
            private Resume3(Experience exp)
            {
                this.Exp =(Experience)exp.Clone();
            }
            public void SetInfo(string name, int age, char gender)
            {
                this.Name = name;
                this.Age = age;
                this.Gender = gender;
            }
            public void SetWorkExp(string timeArea, string company)
            {
                this.Exp.TimeArea = timeArea;
                this.Exp.Company = company;
            }
            public void ShowResume()
            {
                Console.WriteLine($"{this.Name}{this.Age}{this.Gender}");
                Console.WriteLine($"{this.Exp.TimeArea}{this.Exp.Company}");
            }
        }

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档