• Unity设计模式——原型模式


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

    原型类 Prototype:

    1. abstract class Prototype
    2. {
    3. private string id;
    4. public Prototype(string id)
    5. {
    6. this.id = id;
    7. }
    8. public string Id
    9. {
    10. get { return id; }
    11. }
    12. //抽象类关键有这样一个Clone方法
    13. public abstract Prototype Clone();
    14. }

     ConcretePrototypel类,具体原型

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

    客户端

    1. class Main : MonoBehaviour
    2. {
    3. private void Start()
    4. {
    5. ConcretePrototypel pl = new ConcretePrototypel("I");
    6. ConcretePrototypel cl = (ConcretePrototypel)pl.Clone();
    7. Debug.Log("clone" + cl.Id);
    8. }
    9. }

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

     简历类:

    1. class Resume : ICloneable
    2. {
    3. private string name;
    4. private string sex;
    5. private string age;
    6. private string timearea;
    7. private string company;
    8. public Resume(string name)
    9. {
    10. this.name = name;
    11. }
    12. //设置个人信息
    13. public void SetPersonalInfo(string sex,string age)
    14. {
    15. this.sex = sex;
    16. this.age = age;
    17. }
    18. //设置工作经历
    19. public void SetWorkExperrience(string timeArea,string company)
    20. {
    21. this.timearea = timeArea;
    22. this.company = company;
    23. }
    24. //显示
    25. public void Display()
    26. {
    27. //实现接口方法,克隆对象
    28. Debug.Log(name + " " + sex + " " + age);
    29. Debug.Log(timearea + " " + company);
    30. }
    31. public object Clone()
    32. {
    33. return (object)this.MemberwiseClone();
    34. }
    35. }

    客户端:

    1. class Main : MonoBehaviour
    2. {
    3. private void Start()
    4. {
    5. Resume a = new Resume("DJ");
    6. a.SetPersonalInfo("男", "22");
    7. a.SetWorkExperrience("1995-2022", "DJDJ");
    8. //调用克隆方法就可以实现新简历,并且可以修改新简历细节
    9. Resume b = (Resume)a.Clone();
    10. b.SetPersonalInfo("nv", "20");
    11. Resume c = (Resume)a.Clone();
    12. c.SetWorkExperrience("1999-2222", "JJJJ");
    13. a.Display();
    14. b.Display();
    15. c.Display();
    16. }
    17. }

    输出结果:

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

    1. class Resume : ICloneable
    2. {
    3. private string name;
    4. private string sex;
    5. private string age;
    6. private WorkExperience work;///引用“工作经历”对象
    7. public Resume(string name)
    8. {
    9. this.name = name;
    10. work = new WorkExperience();//简历实例化同时实例化工作经历
    11. }
    12. public void SetPersonalInfo(string sex,string age)
    13. {
    14. this.sex = sex;
    15. this.age = age;
    16. }
    17. public void SetWorkExperrience(string workDate,string company)
    18. {
    19. work.WorkDate = workDate;//调用方法,给对象赋值
    20. work.Company = company;
    21. }
    22. public void Display()
    23. {
    24. Debug.Log(name + " " + sex + " " + age);
    25. Debug.Log(work.WorkDate + " " + work.Company);//显示工作经历属性值
    26. }
    27. public object Clone()
    28. {
    29. return (object)this.MemberwiseClone();
    30. }
    31. }
    32. class WorkExperience
    33. {
    34. private string workDate;
    35. public string WorkDate
    36. {
    37. get { return workDate; }
    38. set { workDate = value; }
    39. }
    40. private string company;
    41. public string Company
    42. {
    43. get { return company; }
    44. set { company = value; }
    45. }
    46. }

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

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

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

    深复制流程:

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

    1. class WorkExperience
    2. {
    3. private string workDate;
    4. public string WorkDate
    5. {
    6. get { return workDate; }
    7. set { workDate = value; }
    8. }
    9. private string company;
    10. public string Company
    11. {
    12. get { return company; }
    13. set { company = value; }
    14. }
    15. public object Clone()
    16. {
    17. //工作经历类也实现克隆方法
    18. return (object)MemberwiseClone();
    19. }
    20. }

     然后修改简历类,新增构造函数,方便克隆工作经历类,再修改简历类的克隆方法

    1. class Resume : ICloneable
    2. {
    3. private string name;
    4. private string sex;
    5. private string age;
    6. private WorkExperience work;
    7. public Resume(string name)
    8. {
    9. this.name = name;
    10. work = new WorkExperience();
    11. }
    12. //提供Clone方法调用的私有构造函数,以便克隆工作经历数据
    13. public Resume(WorkExperience work)
    14. {
    15. this.work = (WorkExperience)work.Clone();
    16. }
    17. public void SetPersonalInfo(string sex,string age)
    18. {
    19. this.sex = sex;
    20. this.age = age;
    21. }
    22. public void SetWorkExperrience(string workDate,string company)
    23. {
    24. work.WorkDate = workDate;
    25. work.Company = company;
    26. }
    27. public void Display()
    28. {
    29. Debug.Log(name + " " + sex + " " + age);
    30. Debug.Log(work.WorkDate + " " + work.Company);
    31. }
    32. //调用私有构造方法,让工作经历克隆,然后再给新对象其他字段赋值
    33. //最终返回一个深复制的简历对象
    34. public object Clone()
    35. {
    36. Resume obj = new Resume(this.work);
    37. obj.name = this.name;
    38. obj.sex = this.sex;
    39. obj.age = this.age;
    40. return obj;
    41. }
    42. }

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

  • 相关阅读:
    geemap的详细安装步骤及环境配置
    MyBatis(一)--------十分灵活
    D. Make It Round(math)
    机器语言编写helloworld
    Java-内部类
    SSM框架全套笔记
    【C/C++】什么是POD(Plain Old Data)类型
    分布式存储系统Ceph应用详解
    Iptables扩展模块-connlimit 限制并发连接数
    实时时钟 RTC
  • 原文地址:https://blog.csdn.net/qq_29296473/article/details/133680592