设计模式培训之六:原型模式

查看文章索引请通过http://www.cnblogs.com/seesea125/archive/2012/04/17/2453256.html

一、什么是原型模式?

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

原型模式(Prototype结构图)

未命名

 

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

二、原型模式代码实现:

abstract class prototype
{
      private string id;
      public prototype(string id)
      {
            this.id = id;
      }
      public string Id
     {
      get { return id; }
      set { id = value; }
     } 
     public abstract prototype Clone();//抽象的关键就是这个Clone()这个方法.
}

class ConcretePrototype1:prototype
{
      public ConcretePrototype1(string id)
     : base(id)
     {
}

public override prototype Clone()
{
      return (prototype)this.MemberwiseClone();//创建当前对象的浅表副本。方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其副本引用同一对象。
}

class Program
{
      static void Main(string[] args)
      {
            ConcretePrototype1 c1 = new ConcretePrototype1("123");
            ConcretePrototype1 c2 = (ConcretePrototype1)c1.Clone();//克隆类       ConcretePrototype1的对象C1就能得到新的实例C1.
            Console.WriteLine(c2.Id);
            Console.Read();
     }
}

 

三、.NET 的应用 ICLoneable

但对于.NET而言,那个原型抽象类Prototype是用不着的,因为克隆实在是太常用了,所以.net在system命名空间中提供子ICloneable接口,其中就是唯一的一个方法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 object Clone()
    {
        return (object)this.MemberwiseClone();
    }

    public void SetPersonInfo(string age, string sex)
    {
        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);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Resume re = new Resume("张久宪");
        re.SetPersonInfo("21", "");
        re.SetWorkExperience("2011-2012", "YT");
        re.display();
        Resume re2 = (Resume)re.Clone();
        re2.SetWorkExperience("2012-2013", "其它");
        re2.display();
        Console.Read();
    }
}

 

四、原型模式的优点

每new一次,都需要执行一次构造函数,如果构造函数的执行时间很长,那么多次的执行这个初始化操作就实在是太低效了。一般在初始化的信息不发生变化的情况下,克隆是最好的办法。这即隐藏了对象的细节,又对性能是大大的提高。

意思就是不用重新初始化对象,而是动态地获取对象运行时的状态。

1. 浅复制与深复制

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

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; }
    }

    #region ICloneable 成员
    public object Clone()
    {
        return (WorkExperience)this.MemberwiseClone();
    }
    #endregion
}

class Resume:ICloneable
{
    private string name;
    private string age;
    private string sex;
    private WorkExperience work;
    public Resume(string name)
    {
        this.name = name;
        work = new WorkExperience();
    }

    private Resume(WorkExperience work)
    {
        this.work = (WorkExperience)work.Clone();
    }

    public void setPersonInfo(string age, string sex)
    {
        this.age = age;
        this.sex = sex;
    }

    public void setWorkExperience(string workdate, string company)
    {
        work.WorkDate = workdate;
        work.Company = company;
    }

    public void Display()
    {
        Console.WriteLine("{0} {1} {2}", name, age, sex);
        Console.WriteLine("{0} {1}", work.WorkDate, work.Company);
    }
    #region ICloneable 成员
    public object Clone()
    {
    Resume obj = new Resume(this.work);
    obj.name = this.name;
    obj.age = this.age;
    obj.sex = this.sex;
    return obj;
    }
    #endregion
}

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; }
    }

    #region ICloneable 成员
    public object Clone()
    {
        return (WorkExperience)this.MemberwiseClone(); //工作经历类实现克隆方法
    }
    #endregion
}

class Resume:ICloneable
{
    private string name;
    private string age;
    private string sex;
    private WorkExperience work;
    public Resume(string name)
    {
        this.name = name;
        work = new WorkExperience();
    }

    private Resume(WorkExperience work)
    {
        this.work = (WorkExperience)work.Clone(); //提供Clone方法调用私有构造函数,以便克隆“工作经历的数据”
    }

    public void setPersonInfo(string age, string sex)
    {
        this.age = age;
        this.sex = sex;
    }

    public void setWorkExperience(string workdate, string company)
    {
        work.WorkDate = workdate;
        work.Company = company;
    }

    public void Display()
    {
        Console.WriteLine("{0} {1} {2}", name, age, sex);
        Console.WriteLine("{0} {1}", work.WorkDate, work.Company);
    }

    #region ICloneable 成员
    public object Clone()
    {
        Resume obj = new Resume(this.work); //调用私有方法,让“工作经历”克隆完成,然后再给这个简历对象的相关数据字段赋值,最终返回一个深复制的简历对象.
        obj.name = this.name;
        obj.age = this.age;
        obj.sex = this.sex;
        return obj;
    }
    #endregion

}

class Program
{
    static void Main(string[] args)
    {
        Resume re = new Resume("张久宪");
        re.setPersonInfo("12","");
        re.setWorkExperience("2011","YT");
        re.Display();
        Resume re1 = (Resume)re.Clone();
        re1.setPersonInfo("12", "");
        re1.setWorkExperience("2012", "YT1");
        re1.Display();
        Resume re2 = (Resume)re.Clone();
        re2.setPersonInfo("12", "");
        re2.setWorkExperience("2013", "YT2");
        re2.Display();
        Console.Read();
    }
}

 

2. 原型模式的应用.

DataSet他就有Clone()和copy() 。Clone()方法用来复制的DataSet的结构,但不复制DataSet的数据,实现了原型械的浅复制。Copy()方法不但复制结构,也复制数据,其实就是实现了原型模式的深复制

posted @ 2012-05-18 18:00  赵学智  阅读(1275)  评论(0编辑  收藏  举报