原型模式——浅复制和深复制

       设计模式这本书通过对小菜求职复印简历,给我们引出了原型模式:用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象。其实说简单点就是我们创建好一个模板,然后进行复制,或者将模板修改后进行制……

      由于MemberwiseClone()方法对于字段为值类型的,则对该字段执行逐位复制;如果字段是引用类型,则复制引用但不复制引用的对象,因此原始对象及其复本引用同一对象。所以我们把复制分为浅复制和深复制!

      浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而其所有的对其他对象的引用都仍然指向原来的对象。

       解释:一个对象中的字段有的是值类型的,有的是引用类型的。对于值类型字段来说,它的值就是简单的值,而对于引用类型来说,它的值是地址。浅复制在复制时,就是将这个对象的值字段和引用字段全部复制过去,、获得了这个对象的值和地址。所以当一个对象的引用字段所指向的地址中的变量变化时,所有浅复制对象中的该引用字段都会发生变化。

<span style="font-size:18px;">class Program
    {
        //工作经历
        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; }
            }

        }

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

       我们在“简历”类中设计了一个“设置工作经历”的方法,然后又设计了一个“工作经历”的类,“简历”类直接调用“工作经历”类中的对象。由于这是引用类型,当b和c克隆于a时只是复制了引用,对引用的对象还是指向了原来的对象,所以结果是看到三个引用都是最后一次的设置,因为三个引用都指向了同一个对象。就是a中的引用类型的内容没有复制给b和c,所以b和c都要指向a中的那个部分。

      深复制:把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。

      解释:被复制对象会将所有非引用类型的字段复制给新对象,同时将引用类型指向地址中存的对象复制给新对象。


<span style="font-size:18px;">class Program
    {
        //工作经历
        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; }
            }

        }

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

       “简历“和”工作经历“两个类都要实现克隆接口,在”简历“类中引用一个”工作经历“对象work,然后在”简历“实现克隆方法时调用私有的构造函数,让”工作经历“克隆完成,再进行对象的相关字段赋值。说白了深复制就是”简历“先把”工作经历“中的东西复制过来,所以a中的“工作经历”就不是引用类型,所以在复制给b和c的时候可以直接给复制过去。然后再对b和c进行赋值,就完成了深复制。

        刚开始时,对深复制和浅复制很晕,后来和同学讨论后觉得应该这么理解……如果不对,还请大神来解救!






1) 优秀的程序应该是这样的:阅读时,感觉很优雅;新增功能时,感觉很轻松;运行时,感觉很快速,这就需要设计模式支撑。2) 设计模式包含了大量的编程思想,讲授和真正掌握并不容易,网上的设计模式课程不少,大多讲解的比较晦涩,没有真实的应用场景和框架源码支撑,学习后,只知其形,不知其神。就会造成这样结果: 知道各种设计模式,但是不知道怎么使用到真实项目。本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 图解+框架源码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了设计模式,包括 设计模式七大原则、UML类图-类的六大关系、23种设计模式及其分类,比如 单例模式的8种实现方式、工厂模式的3种实现方式、适配器模式的3种实现、代理模式的3种方式、拷贝等3) 如果你想写出规范、漂亮的程序,就花时间来学习下设计模式吧课程内容和目标本课程是使用Java来讲解设计模式,考虑到设计模式比较抽象,授课采用 图解+框架源码分析的方式1) 内容包括: 设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式:单例模式(8种实现)、抽象工厂模式、原型模式、建造者模式、工厂模式。结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)2) 学习目标:通过学习,学员能掌握主流设计模式,规范编程风格,提高优化程序结构和效率的能力。
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值