1. 简历代码初步实现

class Program
{
    static void Main(string[] args)
    {
        Resume a = new Resume("大鸟");
        a.SetPersonalInfo("男", "29");
        a.SetWorkExperience("1998-2000", "XX公司");

        Resume b = new Resume("大鸟");
        b.SetPersonalInfo("男", "29");
        b.SetWorkExperience("1998-2000", "XX公司");

        Resume c = new Resume("大鸟");
        c.SetPersonalInfo("男", "29");
        c.SetWorkExperience("1998-2000", "XX公司");


        a.Display();
        b.Display();
        c.Display();

        Console.Read();
    }
}

//简历
class Resume
{
    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 SetWorkExperience(string timeArea, string company)
    {
        this.timeArea = timeArea;
        this.company = company;
    }

    //显示
    public void Display()
    {
        Console.WriteLine("{0} {1} {2}", name, sex, age);
        Console.WriteLine("工作经历:{0} {1}", timeArea, company);
    }

}

A: 三份简历需要三次实例化。20份要实例化20次?
B: 如果写错一个字,那也要改20遍?

2. 原型模式

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

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

class Program
{
    static void Main(string[] args)
    {
        ConcretePrototype1 p1 = new ConcretePrototype1("I");
        ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
        Console.WriteLine("Cloned: {0}", c1.Id);

        ConcretePrototype2 p2 = new ConcretePrototype2("II");
        ConcretePrototype2 c2 = (ConcretePrototype2)p2.Clone();
        Console.WriteLine("Cloned: {0}", c2.Id);

        // Wait for user 
        Console.Read();

    }
}

abstract class Prototype
{
    private string id;

    // Constructor 
    public Prototype(string id)
    {
        this.id = id;
    }

    // Property 
    public string Id
    {
        get { return id; }
    }

    public abstract Prototype Clone();
}

class ConcretePrototype1 : Prototype
{
    // Constructor 
    public ConcretePrototype1(string id)
        : base(id)
    {
    }

    public override Prototype Clone()
    {
        // Shallow copy 
        return (Prototype)this.MemberwiseClone();
    }
}


class ConcretePrototype2 : Prototype
{
    // Constructor 
    public ConcretePrototype2(string id)
        : base(id)
    {
    }

    public override Prototype Clone()
    {
        // Shallow copy 
        return (Prototype)this.MemberwiseClone();
    }
}

3. 简历的原型实现

图2

class Program
{
    static void Main(string[] args)
    {
        Resume a = new Resume("大鸟");
        a.SetPersonalInfo("男", "29");
        a.SetWorkExperience("1998-2000", "XX公司");

        Resume b = (Resume)a.Clone();
        b.SetWorkExperience("1998-2006", "YY企业");

        Resume c = (Resume)a.Clone();
        c.SetPersonalInfo("男", "24");


        a.Display();
        b.Display();
        c.Display();


        Console.Read();

    }
}

//简历
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 SetWorkExperience(string timeArea, string company)
    {
        this.timeArea = timeArea;
        this.company = company;
    }

    //显示
    public void Display()
    {
        Console.WriteLine("{0} {1} {2}", name, sex, age);
        Console.WriteLine("工作经历:{0} {1}", timeArea, company);
    }

    public Object Clone()
    {
        return (Object)this.MemberwiseClone();
    }

}

A: 一般在初始化的信息不发生变化的情况下,克隆是最好的办法。这即隐藏了对象创建细节,又对性能是大大的提高。
B: 等于不用重新初始化对象,而是动态地获得对象运行时的状态。

4. 浅复制与深复制

A: 如果字段是值类型的,则对该字段进行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其副本引用用一对象。
图3

class Program
{
    static void Main(string[] args)
    {
        Resume a = new Resume("大鸟");
        a.SetPersonalInfo("男", "29");
        a.SetWorkExperience("1998-2000", "XX公司");

        Resume b = (Resume)a.Clone();
        b.SetWorkExperience("1998-2006", "YY企业");

        Resume c = (Resume)a.Clone();
        c.SetPersonalInfo("男", "24");
        c.SetWorkExperience("1998-2003", "ZZ企业");

        a.Display();
        b.Display();
        c.Display();

        Console.Read();
    }
}

//简历
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 SetWorkExperience(string workDate, string company)
    {
        work.WorkDate = workDate;
        work.Company = company;
    }

    //显示
    public void Display()
    {
        Console.WriteLine("{0} {1} {2}", name, sex, age);
        Console.WriteLine("工作经历:{0} {1}", 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; }
    }
}

三次显示的结果都是最后一次设置的值。
A: 浅复制,被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。但是我们需要把要复制的对象所引用的对象都复制一遍,即深复制,把引用对象的变量指向复制过的新对象,而不是原有的被引用对象。
B: 如果引用有多层(嵌套),怎么办?
A: 深复制要深入多少层,需要事先就考虑好,而且要当心出现循环引用的问题,需要小心处理。

5. 简历的深复制实现

图4

class Program
{
    static void Main(string[] args)
    {
        Resume a = new Resume("大鸟");
        a.SetPersonalInfo("男", "29");
        a.SetWorkExperience("1998-2000", "XX公司");

        Resume b = (Resume)a.Clone();
        b.SetWorkExperience("1998-2006", "YY企业");

        Resume c = (Resume)a.Clone();
        c.SetWorkExperience("1998-2003", "ZZ企业");

        a.Display();
        b.Display();
        c.Display();

        Console.Read();

    }
}

//简历
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();
    }

    private 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("{0} {1} {2}", name, sex, age);
        Console.WriteLine("工作经历:{0} {1}", 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;
    }

}

//工作经历
class WorkExperience : ICloneable
{
    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)this.MemberwiseClone();
    }
}

yuanoung
10 声望1 粉丝

« 上一篇
工厂方法模式
下一篇 »
模版方法模式

引用和评论

0 条评论