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

在学习设计模式中的原型模式中遇到了浅复制和深复制这两个陌生的面孔。它们到底是什么意思?浅和深到底是什么意思?还是需要来仔细研究一下的

首先,了解一下原型模式:用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象。通俗的将其实就是复制。

若收到复制,并不陌生,但是怎么用,我们又该如何用才能达到更加灵活的复制呢?

浅复制:

1.首先要实现最简单的复制,我们用到的一个Clone的方法,具体用法如下:


public override Prototype Clone()

{

return this.MemberwiseClone(); //MemberwiseClone方法用来创建当前的浅表副本

}

我们具体来看一下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; }
        }

public Object Clone()
        {
            return this.MemberwiseClone(); //实现自身类(工作经历类)的浅表复制,由于此时简历中涉及到的数据位值类型,此时可复制自身对象的数据
        }
    }

//简历类

class Resume :ICloneable
    {
        private string name;
        private string sex;
        private string age;
        private WorkExperience work; //此处引用工作经历类中的对象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,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;

}
    }

客户端的代码如下:


static void Main(string[] args)
        {
            Resume a = new Resume("大鸟");
            a.SetPersonalInfo("男", "29");
            a.SetWorkExperience("1998-9-7", "XS"); //此时,我们用三组不同的数据进行检验

Resume b= (Resume)a.Clone ();
            b.SetWorkExperience ("1889-2-3","dfe");

Resume c = (Resume)a.Clone();
            c.SetPersonalInfo("女", "23");

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

Console.Read();
        }

结果如下:

通过深复制,我们就可以实现相同简历不同数据的复制了。

那么,我们来分析一下,代码的具体含义,看看它是如何做到的。

1、们看代码可以知道,简历类与工作经历是一个组合关系。在面向对象语言中,聚合和组合关系通常要出现一个类来引用另一个类的对象或数据来实现二者之间的关联。

2、么我们只要在被引用的类(工作经历类)中利用Clone方法实现自身的浅表复制,此时由于被引用类中的类型为值类型(包括特殊的string类型)是可以实现自身数据的逐位复制的。那么接下来只要在引用类中调用被引用类中事先声明好的构造方法就可以最终事先工作经历的数据复制了。

3、通过引用类中的clone方法,调用被引用类中的构造方法事先工作经历的数据复制后,再对自身类(引用类)其他的字段进行赋值,最终事先深复制。

以上是我个人对原型模式中浅复制和深复制的理解!


原型模式——浅复制VS深复制,码迷,mamicode.com

时间: 2024-10-10 08:20:55

原型模式——浅复制VS深复制的相关文章

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

原型模式涉及一个浅复制和深复制的概念.原型模式可以简单理解为“复制”,但这个复制不是代码的复制.对同一个类,我们可以实例化new三次来“复制”,但如果在初始化的时候构造函数的执行很长,多次实例化就显得效率很低效了.那我们能否只实例化一次,然后“复制”呢? Test test1 = new Test(); Test test2 = test1; Test test3 = test1; 这样写吗?注意这是引用的复制,这实际上还是只有test1一个实例,test2.test3只是复制了其引用而已,如果

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

设计模式这本书通过对小菜求职复印简历,给我们引出了原型模式:用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象.其实说简单点就是我们创建好一个模板,然后进行复制,或者将模板修改后进行制-- 由于MemberwiseClone()方法对于字段为值类型的,则对该字段执行逐位复制:如果字段是引用类型,则复制引用但不复制引用的对象,因此原始对象及其复本引用同一对象.所以我们把复制分为浅复制和深复制! 浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而其所有的对其他对象的引用都仍然指向

也来谈一谈js的浅复制和深复制

1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制问题(Object,Array等),不讨论基本数据类型(null,undefined,string,number和boolean),这些类型的值本身就存储在栈内存中(string类型的实际值还是存储在堆内存中的,但是js把string当做基本类型来处理 ),不存在引用值的情况. 浅复制和深复制都可以实现在已有对象的基础上再生一份的作用,但是对象的实例是存储在堆内存中然后通

python基础之浅复制与深复制

关于列表.字典.元组的浅复制和深复制,数字和字符串没有浅复制和深复制一说.下面我直接用代码来体现: 1 import copy 2 3 names = ['Cahill','Teenglan','Eric','Peggie','Aalto','Baal','Sadie', 4 'Gage','Hagan','Jack','Kaley','Mabel','Lacy','Nadine','Pace','Amy'] 5 6 #浅复制 7 names2 = names.copy() 8 names2[1

JAVA浅复制与深复制

1.浅复制与深复制概念 ⑴浅复制(浅克隆)     多个变量指向一个对象    被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复制(深克隆)     每个变量指向一个对象,同时对象内包含对象,能复制内部对象    被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量.那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象.换言之,深复制把要复

转载:python中的copy模块(浅复制和深复制)

主要是介绍python中的copy模块. copy模块包括创建复合对象(包括列表.元组.字典和用户定义对象的实例)的深浅复制的函数. ########copy(x)########创建新的复合对象并通过引用复制x的成员来创建x的浅复制.更加深层次说,它复制了对象,但对于对象中的元素,依然使用引用.对于内置类型,此函数并不经常使用.而是使用诸如list(x), dict(x), set(x)等调用方式来创建x的浅复制,要知道像这样直接使用类型名显然比使用copy()快很多.但是它们达到的效果是一样

深度解析javascript中的浅复制和深复制

原文:深度解析javascript中的浅复制和深复制 在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有Number,Boolean,String,Null,Undefined,Object五种类型.而Object又包含Function,Array和Object自身.前面的五种类型叫做基本类型,而Object是引用类型.可能有人就要问,为什么要分基本类型和引用类型呢?后面你就会明白的. 我们首先来看看浅复制和深复制的简洁定义: 深复制:直接将数据复制给

c++中浅复制与深复制

在C++中经常会遇到有关类对象的浅复制与深复制的问题,也是容易出错的地方. 查找了相关资料,有关浅复制与深复制的定义为:对类进行复制的时候按位复制,即把一个对象各数据成员的值原样复制到目标对象中.当类中涉及到指针类型数据成员的时候,往往就会产生指针悬挂问题. class A{ public: int* a; }; A a1; A b1=a1; b1=a1执行的是浅复制,此时a1.a和b1.a指向的是同一个内存地址,如果在析构函数里面有对内存的释放.就会出现内存访问异常.因为一块内存空间会被释放两

java基础-浅复制与深复制的理解

浅复制与深复制在很多编程语言中都有出现,那么什么是浅复制,什么是深复制呢? 要区分浅复制与深复制,首先我们要明确什么是复制,怎样才算是复制.复制的例子在生活中也随处可见,如复印一份文档,复制一段文字等.我们可以发现,复制操作后可以得到两份相同的东西,即复制由一变为二了.下面来看一个例子: public class User{ private int age; public int getAge(){ return age; } } User user1 = new User(); User us