zoukankan      html  css  js  c++  java
  • 原型模式

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

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

      原型模式UML图:

        

      原型模式的基本代码结构:

    namespace ConsoleApplication1
    {
        abstract class Prototype
        {
            private string id;
    
            public Prototype(string id)
            {
                this.id = id;
            }
    
            public string Id
            {
                get { return id; }
            }
    
            public abstract Prototype 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 p1 = new ConcretePrototype1("I");
                ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();     //原型模式创建对象
                Console.WriteLine("Cloned:{0}",c1.Id);  //输出 Cloned:I
    
                Console.ReadKey();
            }
        }  
    }

      原型模式的作用:我们知道每new一次对象,都需要执行一次构造函数,如果构造函数的执行时间很长,那么多次的执行初始化操作就比较低效。一半在初始化的信息不发生变化的情况下,克隆是最好的办法,这既隐藏了对象创建的细节,又能对性能是大大的提高。不用重新初始化对象,而是动态地获得对象运行时的状态。

      在使用原型模式中,有必要注意浅复制与深复制的概念。

      对于上面的原型结构示例代码:我们知道如果字段是值类型的,则对该字段执行逐位复制,如果字段是引用类型的,则复制引用但不复制引用的对象;因此,原始对象及其副本引用同意对象。

      浅复制:被复制对象的所有变量都含有与原来对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。也就是说,浅复制复制出来的对象,如果里面含有引用类型的数据,则浅复制复制出来的对象与原对象是同一个,因为仅复制引用地址嘛。

      深复制:当执行复制时,被复制的对象含有引用类型对象的变量时,引用类型的变量对象也重新复制一份,即复制出来的引用对象与原类中的对象不是指向同一个地址。

      因此,在使用原型模式时必须要分析好,是该浅复制还是深复制。

      回到《大话设计模式中的示例》 简历的原型实现:

    namespace ConsoleApplication1
    {
        class WorkExperience : ICloneable   //主要,要让工作经历实现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();
            }
        }
        
        //简历类
        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();   //注意深复制必须要添加此段代码,提供Clone方法调用的私有构造函数以便克制工作经历
            }
    
            //设置个人信息
            public void SetPersonnalInfo(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 Program
        {
            static void Main(string[] args)
            {
                Resume a = new Resume("大鸟");
                a.SetPersonnalInfo("","29");
                a.SetWorkExperience("1998-2000","微软");
    
                Resume b = (Resume)a.Clone();
                b.SetWorkExperience("2000-2004","google");
    
                Resume c = (Resume)a.Clone();
                c.SetPersonnalInfo("","24");
                c.SetWorkExperience("1998-2004","苹果");
    
                a.Display();
                b.Display();
                c.Display();
    
                Console.ReadKey();
            }
        }  
    }

      

  • 相关阅读:
    [ACM训练] 数据结构----树、二叉树----c++ && python
    [机器学习] ——KNN K-最邻近算法
    [Python学习] Linux环境下的Python配置,必备库的安装配置
    [Python学习] python 科学计算库NumPy—矩阵运算
    [Python学习] python 科学计算库NumPy—tile函数
    [机器学习] ——初识及实践选择
    [机器学习] 虚拟机VMware中使用Ubuntu的联网问题
    使用ScribeFire,Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结
    工作常用 随笔记录
    JavaScript取子串方法slice,substr,substring对比表
  • 原文地址:https://www.cnblogs.com/qixuejia/p/4512079.html
Copyright © 2011-2022 走看看