大话设计模式-原型模式

原型模式

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

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


原型模式结构演示

原型抽象类: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
        };
    }
}

猜你喜欢

转载自www.cnblogs.com/errornull/p/10031367.html
今日推荐