原型模式——找工作要复印简历

  原型模式(Prototype)定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
  例子背景: 找工作需要准备大量的简历,可是我不想一份一份的码字,于是想起了复制粘贴功能。朋友也托我帮他做简历,格式可以全完复制粘贴,要想让简历内容不一样,就需要用到深复制功能,这里用显示不同工作经历举例。
  复制功能还有浅复制、深复制的区别。


在这里插入图片描述

原型类:.net提供了ICloneable接口,其中就有方法Clone(),所以其实不必写原型类,实现接口即可。

abstract class Prototype
{
    
    
	private string id;		
	public Prototype(string id)		//构造函数重载
	{
    
    
		this.id=id;
	}
	public string Id		//Id属性只读
	{
    
    
		get {
    
    return id;}
	}
	public abstract Prototype Clone(); //抽象类的Clone方法
}

具体原型类:

//具体原型类实现复制
class ConcretePrototype1:Prototype
{
    
    
	public ConcretePrototype1(string id):base(id)
	{
    
    }
	public override Prototype Clone()	//重写Clone方法
	{
    
    
		return (Prototype)this.MemberwiseClone();	//MemberwiseClone()就是浅复制
	}
}

客户端代码:

static void Main (string[] args)
{
    
    
	ConcretePrototype1 p1 = new ConcretePrototype1("I");
	ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();	//把Clone后的值强转成ConcretePrototype1类型
	Console.WriteLine("Clone:{0}",c1.Id);
	Console.Read();
}


  浅复制: MemberwiseClone()方法,当字段是值类型,则逐位复制;当字段是引用类型,则复制引用,不复制引用的对象。

工作经历类:

    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, sex, 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.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();		//这里用到浅复制方法了
        }

客户端:

		static void Main(string[] args)
        {
    
    
            Resume a = new Resume("飞机");
            a.SetPersonalInfo("男","29");
            a.SetWorkExperience("2020年11月29日","九天星月公司");

            Resume b = (Resume)a.Clone();	//a的值浅复制给了b
            b.SetWorkExperience("2020年11月29日","米西我的超人公司");	 //引用被覆盖

            Resume c = (Resume)a.Clone();	//a的值浅复制给了c
            c.SetPersonalInfo("男","24");	//重新复制
            c.SetWorkExperience("2020年11月30日","瓜里瓜气公司");	//引用被覆盖
            a.Display();
            b.Display();
            c.Display();

            Console.Read();
        }

显示:显示的工作经历都是最后一次的值

飞机 男 29
工作经历:20201130日 瓜里瓜气公司
飞机 男 29
工作经历:20201130日 瓜里瓜气公司
飞机 男 24
工作经历:20201130日 瓜里瓜气公司


  深复制: 把引用的对象的变量指向复制过的新对象,而不是原有的引用对象。


工作经历类:

class WorkExperience:ICloneable //实现了接口
{
    
    
	省略……
}
public Object Clone()	//实现克隆方法
{
    
    
	return (object)this.MemberwiseClone();	//依然是MemberwiseClone(),但简历类里传值方式会有改变
}

简历类:

class Resume:ICloneable		//实现接口
    {
    
    
        private string name, sex, age;

        private WorkExperience work; //引用工作经历对象

        public Resume(string name)
        {
    
    
            this.name = name;
            work = new WorkExperience(); //在简历类实例化同时实例化工作经历
        }
        private Resume(WorkExperience work)//构造函数,参数是工作经历类型
        {
    
    
            this.work = (WorkExperience)work.Clone(); //这里的Clone()方法是工作经历类里的方法,浅复制了引用
        }
        //设置个人信息
        public void SetPersonalInfo(string sex,string age)
        {
    
    
            不变,省略……
        } 
        //设置工作经历
        public void SetWorkExperience(string workDate, string company)
        {
    
    
			不变,省略……
        }
        //显示
        public void Display()
        {
    
    
            不变,省略……
        }
        public Object Clone()
        {
    
    
        	//使用构造方法,让工作经历浅复制完成,赋值给新对象,而不是原来被引用的对象
            Resume obj = new Resume(this.work); 
            obj.name = this.name;
            obj.sex = this.name;
            obj.age = this.age;
            return obj;
        }

客户端代码不变。
显示:这次三次工作经历都不相同。

飞机 男 29
工作经历:20201129日 九天星月公司
飞机 大鸟 29
工作经历:20201129日 米西我的超人公司
飞机 男 24
工作经历:20201130日 瓜里瓜气公司

猜你喜欢

转载自blog.csdn.net/CharmaineXia/article/details/110662622