zoukankan      html  css  js  c++  java
  • 大话设计模式-原型模式

    原型模式

    用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

    原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。


    原型模式结构演示

    原型抽象类:Prototype

    abstract class Prototype{
        public string Id { get; set; }
        public Prototype(string id) => Id = id;
        public abstract Prototype Clone();
    }

    具体原型类:ConcretePrototype1

    class ConcretePrototype1 : Prototype{
        public ConcretePrototype1(string id) : base(id){ }
        public override Prototype Clone() => (Prototype)this.MemberwiseClone();
    }

    测试类:Program

    ConcretePrototype1 p1 = new ConcretePrototype1("A");
    ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
    Console.WriteLine("Cloned:"+c1.Id);
    //结果
    Cloned:A

    对于.NET而言,原型抽象类Prototypr使用不到的,因为克隆很常用,.NET在System命名空间提供了ICloneable接口,其中一个方法就是Clone(),只需要实现这个接口就可以完成原型克隆了。


    简历的原型实现

    简历类:Resume

    class Resume : ICloneable{
        private string name, sex, age, timeArea, company;
        public Resume(string name) => this.name = name;
        public void SetPersonalInfo(string sex, string age){
            this.sex = sex;
            this.age = age;
        }
        public void SetWorkExperience(string timeArea,string company){
            this.timeArea = timeArea;
            this.company = company;
        }
        public void Display(){
            Console.WriteLine($"{name},{sex},{age}");
            Console.WriteLine($"工作经历:{timeArea},{company}");
        }
        public object Clone() => MemberwiseClone();
    }

    测试类:Program

    //简历a
    Resume a = new Resume("曹丞相");
    a.SetPersonalInfo("","29");
    a.SetWorkExperience("2017-2018", "网易公司");
    //简历b,修改工作经历
    Resume b = (Resume)a.Clone();
    b.SetWorkExperience("2018-2019", "腾讯公司");
    //简历c,修改年龄
    Resume c = (Resume)a.Clone();
    c.SetPersonalInfo("", "30");
    //显示
    a.Display();
    b.Display();
    c.Display();
    //测试结果
    曹丞相,男,29
    工作经历:2017-2018,网易公司
    曹丞相,男,29
    工作经历:2018-2019,腾讯公司
    曹丞相,男,30
    工作经历:2017-2018,网易公司

     


    浅复制与深复制

    MemberwiseClone()方法是这样的,如果字段是值类型就对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象,因此原始对象及其副本引用同一对象。即浅复制。


    简历的深复制实现

    工作经历类:WorkExperience

    假如增加工作经历类,将工作时间和公司封装到工作经历类。

    class WorkExperience : ICloneable{
        public string WorkDate { get; set; }
        public string Conpany { get; set; }
        public Object Clone() => MemberwiseClone();
    }

    简历类:Resume

    修改简历类的字段、构造器、设置工作经历方法和Clone方法。

    class Resume : ICloneable{
        private string name, sex, age;
        private WorkExperience work;
        //构造器
        public Resume(string name){
            this.name = name;
            work = new WorkExperience();
        }
        public Resume(WorkExperience work) => this.work = (WorkExperience)work.Clone();
        //设置个人信息
        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(
            $"{name},{sex},{age + Environment.NewLine}工作经历:{work.WorkDate},{work.Company}"
        );
        //克隆简历
        public object Clone()
        {
            //调用私有的构造方法,让工作经历类克隆完成
            //再给简历对象的字段复制,最终返回一个深复制的简历对象
            return new Resume(work){
                name = name,
                sex = sex,
                age = age
            };
        }
    }
  • 相关阅读:
    SpringMVC_day02
    Linux下安装jdk,tomcat,mysql
    SpringMVC_day01
    如何在虚拟机中安装kali linux
    Shell中 &>/dev/null和 >/dev/null 2>&1
    Linux 安全加固2
    linux 安全加固
    记一次修改php.ini不生效的踩坑之旅
    Redis 参数详解
    LAMP + Redis 主从复制
  • 原文地址:https://www.cnblogs.com/errornull/p/10031367.html
Copyright © 2011-2022 走看看