zoukankan      html  css  js  c++  java
  • 设计模式培训之六:原型模式

    查看文章索引请通过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()方法不但复制结构,也复制数据,其实就是实现了原型模式的深复制

  • 相关阅读:
    JDK里面包含jre,为什么还要下载一个jre呢?
    2021年11月2日,面试经历
    linux内核学习心得
    关于QQ短信接口的使用。
    软件测试--开发者测试例子
    此博客相关声明·AP2017060911I
    21RNC201906034I·代码重构
    20RNC201901313I·代码重构
    19RND201808172·层次设定
    18RND201801311·图像方案日记
  • 原文地址:https://www.cnblogs.com/seesea125/p/2508179.html
Copyright © 2011-2022 走看看