当前位置: 首页 > news >正文

Unity设计模式——原型模式

        原型模式(Prototype)用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需知道任何创建的细节 。

原型类 Prototype:

abstract class Prototype
{private string id;public Prototype(string id){this.id = id;}public string Id{get { return id; }}//抽象类关键有这样一个Clone方法public abstract Prototype Clone();
}

 ConcretePrototypel类,具体原型

class ConcretePrototypel : Prototype
{public ConcretePrototypel(string id) : base(id) { }public override Prototype Clone(){//创建一个新对象,然后将当前对象非静态字段复制到该新对象//如果字段是值类型,则逐位复制字段,引用类型只复制引用地址return (Prototype)this.MemberwiseClone();}
}

客户端:

class Main : MonoBehaviour
{private void Start(){ConcretePrototypel pl = new ConcretePrototypel("I");ConcretePrototypel cl = (ConcretePrototypel)pl.Clone();Debug.Log("clone" + cl.Id);}
}

由于克隆实在太常用,.Net在System命名空间提供了IClone接口,唯一的Clone()方法,只要实现这个接口就可以完成原型模式了。

 简历类:

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;}//设置个人信息public void SetPersonalInfo(string sex,string age){this.sex = sex;this.age = age;}//设置工作经历public void SetWorkExperrience(string timeArea,string company){this.timearea = timeArea;this.company = company;}//显示public void Display(){//实现接口方法,克隆对象Debug.Log(name + " " + sex + " " + age);Debug.Log(timearea + " " + company);}public object Clone(){return (object)this.MemberwiseClone();}
}

客户端:

class Main : MonoBehaviour
{private void Start(){Resume a = new Resume("DJ");a.SetPersonalInfo("男", "22");a.SetWorkExperrience("1995-2022", "DJDJ");//调用克隆方法就可以实现新简历,并且可以修改新简历细节Resume b = (Resume)a.Clone();b.SetPersonalInfo("nv", "20");Resume c = (Resume)a.Clone();c.SetWorkExperrience("1999-2222", "JJJJ");a.Display();b.Display(); c.Display();}
}

输出结果:

        现实设计当中,一般会再有一个“工作经历”类,当中有“时间区间”和“公司名称”等属性,“简历”类直接调用。

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 SetWorkExperrience(string workDate,string company){work.WorkDate = workDate;//调用方法,给对象赋值work.Company = company;}public void Display(){Debug.Log(name + " " + sex + " " + age);Debug.Log(work.WorkDate + " " + work.Company);//显示工作经历属性值}public object Clone(){return (object)this.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; }}
}

使用之前的客户端逻辑,运行后结果:

        对于引用类型,克隆后没有实现真正的克隆,而是只克隆了引用地址,这叫做“浅复制”,被复制对象的所有变量都含有与原来的对象相同的值;而所有的对其他对象的引用都仍然指向原来的对象。

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

深复制流程:

首先修改WorkExperience类,增加克隆方法

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; }}public object Clone(){//工作经历类也实现克隆方法return (object)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();}//提供Clone方法调用的私有构造函数,以便克隆工作经历数据public Resume(WorkExperience work){this.work = (WorkExperience)work.Clone();}public void SetPersonalInfo(string sex,string age){this.sex = sex;this.age = age;}public void SetWorkExperrience(string workDate,string company){work.WorkDate = workDate;work.Company = company;}public void Display(){Debug.Log(name + " " + sex + " " + age);Debug.Log(work.WorkDate + " " + 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;}
}

还是使用之前的客户端逻辑,结果如下。 

http://www.lryc.cn/news/187105.html

相关文章:

  • leetcode 96 不同的二叉搜索树
  • http发送和接收图片json文件
  • MM-Camera架构-ProcessCaptureRequest 流程分析
  • 196、管理 RabbitMQ 的用户
  • 【已解决】Python读取sql数据,报错:Not an executable object,解决方案
  • STM32 CubeMX ADC采集(HAL库)
  • [UUCTF 2022 新生赛]ezpop - 反序列化+字符串逃逸【***】
  • Selenium进行无界面爬虫开发
  • 万宾荣获深圳应博会“全球应急产业先锋奖”创始人发表峰会演讲
  • 某果的一个小参数分析
  • java学习--day22(进程线程)
  • 对音频切分成小音频(机器学习用)
  • TensorFlow案例学习:对服装图像进行分类
  • 单目3D目标检测——SMOKE 模型推理 | 可视化结果
  • C++智能指针shared_ptr使用详解
  • 基于Java的个性化旅游攻略系统设计与实现(源码+lw+ppt+部署文档+视频讲解等)
  • 中国替代方案探索:替代谷歌企业邮箱的选择
  • Holographic MIMO Surfaces (HMIMOS)以及Reconfigurable Holographic Surface(RHS)仿真
  • RK3568笔记一:RKNN开发环境搭建
  • 设计模式 - 行为型模式:策略模式(概述 | 案例实现 | 优缺点 | 使用场景)
  • rancher部署pv、pvc、离线部署nfs
  • 视频拍摄教程分享
  • IP组成,分类,子网划分
  • Python视频剪辑-Moviepy视频内容变换技术
  • OceanBase 数据库入门知识
  • 自定义无边框窗口
  • 【网络安全 --- kali2023安装】超详细的kali2023安装教程(提供镜像资源)
  • 机器学习笔记(二)
  • Java @Override 注解
  • 用rabbitMq 怎么处理“延迟消息队列”?