2016.12.20 学习日记-原型模式

后天考大物还有太多不懂,感觉有点不妙啊~~~今天学习的是原型模式。


原型模式(Prototype):

原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。

优点及适用场景

使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。

使用原型模式的另一个好处是简化对象的创建,使得创建对象就像我们在编辑文档时的复制粘贴一样简单。

因为以上优点,所以在需要重复地创建相似对象时可以考虑使用原型模式。比如需要在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数很多的话,使用原型模式不但可以简化创建过程,而且可以使系统的整体性能提高很多。

注意事项

使用原型模式复制对象不会调用类的构造方法。因为对象的复制是通过调用Object类的clone方法来完成的,它直接在内存中复制数据,因此不会调用到类的构造方法。不但构造方法中的代码不会执行,甚至连访问权限都对原型模式无效。还记得单例模式吗?单例模式中,只要将构造方法的访问权限设置为private型,就可以实现单例。但是clone方法直接无视构造方法的权限,所以,单例模式与原型模式是冲突的。

在使用时要特别注意。深拷贝与浅拷贝。Object类的clone方法只会拷贝对象中的基本的数据类型,对于数组、容器对象、引用对象等都不会拷贝,这就是浅拷贝。如果要实现深拷贝,必须将原型模式中的数组、容器对象、引用对象等另行拷贝


实例(简历的深复制):

Resume.cs

 class Resume : ICloneable
    {
        private string name;
        private int 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 SetPersonalInfo(string sex, int 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.age = this.age;
            obj.sex = this.sex;
            return obj;
        }

    }

WorkExperience.cs

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

Program.cs

class Program
    {
        static void Main(string[] args)
        {
            Resume a = new Resume("Tracy");
            a.SetPersonalInfo("male", 19);
            a.SetWorkExperience("2016-2017", "Tencent");

            Resume b = (Resume)a.Clone();
            b.SetWorkExperience("2010-2017", "Baidu");

            Resume c = (Resume)a.Clone();
            c.SetPersonalInfo("female", 25);

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

            Console.ReadKey();
        }
    }

简单地说,原型模式隐藏了对象创建的细节,又对性能有了大大的提升。他不用重新初始化对象,而是动态地获得对象运行时的状态。但需特别注意浅复制与深复制。MemberwiseClone()方法,如果字段是值类型,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制当前对象,因此,原始对象极其副本引用同一对象。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值