【设计模式】——原型模式

来源:互联网 发布:淘宝情趣珍珠内裤评论 编辑:程序博客网 时间:2024/06/12 00:18

在原型模式中我们可以利用过一个原型对象来指明我们所要创建对象的类型,然后通过复制这个对象的方法来获得与该对象一模一样的对象实例。这就是原型模式的设计目的。

一、模式定义

    用原型实例创建指定创建对象的种类,并且通过拷贝这些原型创建新的对象。其实原型模式就是从一个对象创建另外一个可定制的对象,并且不需要知道任何创建的细节。


二、浅复制和深复制

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

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

浅复制

//浅复制    //工作经历类    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 wordDate, string company) //调用此方法时,给对象的两属性赋值。        {            Work.WorkDate = wordDate;            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();        }    }

控制台输出:



关于浅复制一个非常直观的表示就是,在控制台输出的结果显示,结果只是显示了工作经历中关于“zz企业”的这一段期间,反应到代码上就是在显示abc对象的时候其实都是指向了一个共同的对象,如下图。



对于图中的理解就是abc的引用都是指向一个对象,当b克隆了a对象的东西之后,并且更新了对象,其实也就更新了a应用指向的对象,当c再次的克隆a对象的时候这时候克隆的对象,就是经过b更新之后的对象。很显然浅复制并不能满足我们的实际需求。

深复制

 //深复制    //工作经历类    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();        }    }    //简历类    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 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;        }    }

控制台输出:


深复制之后的结果符合我们的要求,可以显示不同的工作经历。证明abc分别指向了不同的对象。在代码中有一个明显的不同就是,在代码中对于resume对象的构造函数进行了重构。之后的克隆方法调用了新的构造函数,在这里创建了一个新的对象。新的构造函数所需要的参数就是通过需要克隆的方法进行传参,也就是对象a的内容。如下图。


对于图中的理解很明显就是创建了不同的对象,当然这都是通过原型模式进行克隆的。b克隆了a对象,并创建了一个新的对象,然后指向新对象。c克隆了a对象,也创建了一个新对象,然后指向新对象。

 在对于深浅赋值的区分方面,主要就看有没有对于构造函数进行重构,这是最大的区别。

三、模型优缺点

优点:

1、如果创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同时也能够提高效率。

2、可以使用深克隆保持对象的状态。

3、原型模式提供了简化的创建结构。

缺点:

 1、在实现深克隆的时候可能需要比较复杂的代码。

2、需要为每一个类配备一个克隆方法,而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事,必须修改其源代码,违背了“开闭原则”。 

四、模式总结

1、原型模式向客户隐藏了创建对象的复杂性。客户只需要知道要创建对象的类型,然后通过请求就可以获得和该对象一模一样的新对象,无须知道具体的创建过程。

2、克隆分为浅克隆和深克隆两种。

3、我们虽然可以利用原型模式来获得一个新对象,但有时对象的复制可能会相当的复杂,比如深克隆。


0 0