原型模式 订阅
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 展开全文
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
信息
外文名
Prototype
问    题
结构复杂的对象”的创建工作
实    现
clone()方法来实现对象的克隆
中文名
原型模式
模    式
Prototype
原型模式定义
原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。 [1] 
收起全文
精华内容
下载资源
问答
  • 原型模式

    2020-12-26 17:11:55
    原型模式

    使用场景

        当需要重复创建对象时,且创造对象比较复杂耗时,这时我们可以采用克隆的方式来优化,既今天要说的原型模式。

    原型模式核心方法介绍

        原型模式是基于方法MemberwiseClone()实现的,MemberwiseClone() 在C#是一个浅复制的方法。
        问题来了什么是浅复制?
    方法MemberwiseClone() 只能且仅能复制对象的值类型,如果是引用类型只能复制其引用,不会复制引用的数据,这就导致复制的源对象上有引用类型的数据,复制的对象和源对象会引用同一个数据。
         数据怎么存储?
        我们的数据是存放在堆和栈上的,引用类型一定是放在堆上的,局部变量是放在栈上的,局部变量中的字段跟随所在变量存储。

    示例

        以生活中的简历为例,一个人会有不同阶段的工作经历,使用原型模式复制工作经历。

     //工作经历
     public class WorkExperience
     {
         public string WorkDate { get; set; }
         public string CompanyName { get; set; }
     }
    
     //简历
     public class Resume
     {
         private string Name { get; set; }
         private string Sex { get; set; }
         private int Age { get; set; }
         private WorkExperience work;
    
         public Resume(string name) {
             this.Name = name;
             work = new WorkExperience();
         }
    
         //设置个人信息
         public void SetPersonInfo(string sex,int age) {
             this.Sex = sex;
             this.Age = age;
         }
    
         //设置工作经历
         public void SetWorkExperience(string date,string companyName) {
             work.WorkDate = date;
             work.CompanyName = companyName;
         }
    
         //展示简历
         public void Show() {
             Console.WriteLine("姓名:{0}  性别:{1}  年龄:{2}",Name,Sex,Age);
             Console.WriteLine("工作经历:{0} {1}",work.WorkDate,work.CompanyName);
         }
    		
    	 //复制对象
         public Object Clone() {
             return this.MemberwiseClone();
         }
     }
    

    实现

     static void Main(string[] args)
     {
         Resume resume1 = new Resume("张三");
         resume1.SetPersonInfo("男",26);
    
         //公司:温州皮革厂经历
         resume1.SetWorkExperience("2017-01-01","温州皮革厂");
    
         //公司:金华皮革厂经历
         Resume resume2 = (Resume)resume1.Clone();
         resume2.SetWorkExperience("2018-01-01", "金华皮革厂");
    
         //公司:江南皮革厂经历
         Resume resume3 = (Resume)resume1.Clone();
         resume3.SetWorkExperience("2019-01-01", "江南皮革厂");
    
         resume1.Show();
         resume2.Show();
         resume3.Show();
     }
    

    在这里插入图片描述
        可以看到对于姓名,性别,年龄内容都已经复制,不同阶段的年龄是不同的,但工作经历却复制失败了,从之前的分析方法MemberwiseClone()浅复制的作用可以知道,工作经历是引用的对象,三个阶段的工作经历实际在堆上只有一份数据,他们都是同时引用同一个工作经历对象,所有最后工作阶段改变了工作经历,导致前面的工作经历也变化了,那么怎么去解决这个浅复制,做到真正的原型模式呢,看下面…

     //工作经历
     public class WorkExperience
     {
         public string WorkDate { get; set; }
         public string CompanyName { get; set; }
         //复制对象
         public Object Clone()
         {
             return this.MemberwiseClone();
         }
     }
     public class Resume
     {
         private string Name { get; set; }
         private string Sex { get; set; }
         private int Age { get; set; }
         private WorkExperience work;
    
         public Resume(string name) {
             this.Name = name;
             work = new WorkExperience();
         }
    
         public Resume(WorkExperience work)
         {
             this.work = (WorkExperience)work.Clone();
         }
    
         //设置个人信息
         public void SetPersonInfo(string sex,int age) {
             this.Sex = sex;
             this.Age = age;
         }
    
         //设置工作经历
         public void SetWorkExperience(string date,string companyName) {
             work.WorkDate = date;
             work.CompanyName = companyName;
         }
    
         public void Show() {
             Console.WriteLine("姓名:{0}  性别:{1}  年龄:{2}",Name,Sex,Age);
             Console.WriteLine("工作经历:{0} {1}",work.WorkDate,work.CompanyName);
         }
    
         public Object Clone() {
             //复制工作经历,使得每个工作经历对象独立
             Resume resume = new Resume(this.work);
             resume.Name = this.Name;
             resume.Sex = this.Sex;
             resume.Age = this.Age;
             return resume;
         }
     }
    

        这样就实现了原型模式
    在这里插入图片描述

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 26,339
精华内容 10,535
关键字:

原型模式