设计模式之原型模式

一.引入

小菜的问题:要把简历发到多家公司,简历的份数就必须足够。

大鸟的回答:用编程来复制自己简历。

二.解决过程

① 最初的写法:

 简历类:

<span style="font-family:KaiTi_GB2312;font-size:24px;">class Resume
        {
            private string name;
            private string sex;
            private string age;
            private string timeArea;
            private string company;

            public Resume(string name)
            {
                this.name = name;
            }

            //设置个人信息
            public void SetPersonalInfo(string sex, string age)
            {
                this.sex = sex;
                this.age = age;
            }
            //设置工作经历
            public void SetWorkExperience(string timeArea, string company)
            {
                this.timeArea = timeArea;
                this.company = company;
            }
            //显示
            public void Display()
            {
                Console.WriteLine("{0} {1} {2}", name, sex, age);
                Console.WriteLine("工作经历:{0} {1}", timeArea, company);
            }
        }
</span>

客户端调用代码:

<span style="font-family:KaiTi_GB2312;font-size:24px;">static void Main(string[] args)
        {
            Resume a = new Resume("大鸟");
            a.SetPersonalInfo("男", "29");
            a.SetWorkExperience("1998-2000", "XX公司");

            Resume b = new Resume("大鸟");
            b.SetPersonalInfo("男", "29");
            b.SetWorkExperience("1998-2000", "XX公司");

            Resume c = new Resume("大鸟");
            c.SetPersonalInfo("男", "29");
            c.SetWorkExperience("1998-2000", "XX公司");

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

            Console.Read();
        }</span>

这样,确实可以做到复制出多份简历,但想要修改简历,每一个实例化的简历都需要修改。这样的工作就很庞大了。

② 传引用写法:

<span style="font-family:KaiTi_GB2312;font-size:24px;">static void Main(string[] args)
        {
            Resume a = new Resume("大鸟");
            a.SetPersonalInfo("男", "29");
            a.SetWorkExperience("1998-2000", "XX公司");

            Resume b = a;
            Resume c = a;

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

            Console.Read();
        }</span>

这样,代码虽然简单了,但根本没有做到复制简历,b和c纸张上无法将a上的内容得到。

三.应用

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

创建原型类:

<span style="font-family:KaiTi_GB2312;font-size:24px;"> abstract class Prototype
        {
            private string id;
            public Prototype(string id)
            {
                this.id = id;
            }
            public string Id
            {
                get { return id; }
            }
            public abstract Prototype Clone();//抽象类的关键方法Clone
        }</span>

具体原型类:

<span style="font-family:KaiTi_GB2312;font-size:24px;">class ConcretePrototype1 : Prototype
        {
            public ConcretePrototype1(string id)
                : base(id)
            {
            }
            public override Prototype Clone()
            {
                return (Prototype)this.MemberwiseClone();
            }
        }
</span>

客户端代码:

<span style="font-family:KaiTi_GB2312;font-size:24px;">        static void Main(string[] args)
        {
            ConcretePrototype1 p1 = new ConcretePrototype1("I");
            ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
            Console.WriteLine("Cloned:{0}", c1.Id);
            Console.Read();
        }</span>

利用ICloneable接口实现简历原型:

简历类:

<span style="font-family:KaiTi_GB2312;font-size:24px;">class Resume : ICloneable
        {
            private string name;
            private string sex;
            private string age;
            private string timeArea;
            private string company;

            public Resume(string name)
            {
                this.name = name;
            }
            //设置个人信息
            public void SetPersonalInfo(string sex, string age)
            {
                this.sex = sex;
                this.age = age;
            }
            //设置工作经历
            public void SetWorkExperience(string timeArea, string company)
            {
                this.timeArea = timeArea;
                this.company = company;
            }
            //显示
            public void Display()
            {
                Console.WriteLine("{0} {1} {2}", name, sex, age);
                Console.WriteLine("工作经历:{0} {1}", timeArea, company);
            }
            public object Clone()
            {
                return (object)this.MemberwiseClone();
            }
<span style="white-space:pre">	</span>}</span>

客户端代码:

<span style="font-family:KaiTi_GB2312;font-size:24px;">            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", "XX公司");

                Resume c = (Resume)a.Clone();
                c.SetWorkExperience("男", "24");

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

                Console.Read();
            }
</span>

四.扩展

① 浅复制:

被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。这样的定义很难理解,就拿实例结果说话吧:

原本想要前图那样的效果,结果却是后图。这样一个过程也就是浅复制的过程,看似复制了,但实际上内容并没有得到复制。

② 深复制:

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

工作经历类:

<span style="font-family:KaiTi_GB2312;font-size:24px;">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();//“工作经历”类实现克隆方法
        }</span>

简历类:

<span style="font-family:KaiTi_GB2312;font-size:24px;">private Resume(WorkExperience work)
        {
            this.work = (WorkExperience)work.Clone();//提供Clone方法调用的私有构造函数,以便克隆“工作经历”的数据
        }</span>
<span style="font-family:KaiTi_GB2312;font-size:24px;">public Object Clone()
        {
            Resume obj = new Resume(this.work);//调用私有的构造方法,让“工作经历”克隆完成,然后再给“简历”对象的相关字段赋值
            obj.name = this.name;
            obj.sex = this.sex;
            obj.age = this.age;
            return obj;
        }</span>

从而达到我们想要的结果,如下图:

五.学习心得

对于这一过程的学习,觉得原型模式很简单,生活中也很常见,只要给出一个原型的种类就行。复制简历,是一个很常见的实例,运用原型模式,也确实是最佳体现。至于后面的浅复制与深复制的学习,刚开始不知道他们想表达的是什么意思,于是从结果出发,浅复制的结果不是所想要得到的,深复制才是,这时候便去研究两者的代码,两者的结构图,才发现,其实也很简单,只要将“工作经历”这一类同样利用接口去实现,就可以达到其想要达到的效果了。

时间: 2024-12-24 21:47:34

设计模式之原型模式的相关文章

java设计模式---prototype(原型)模式

设计 java设计模式---prototype(原型)模式 定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.      Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,      工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求      原型对象拷贝它们自己来实施创建.      适用性:当要实例化的类是在运行时刻指定时,例如,通过动态装载:或者  为了避免创建一个与产品类层次平行的工厂类层

浅谈Java设计模式关于原型模式(Prototype)思索建议

java教程:关于Java设计模式关于原型模式(Prototype) IT信息技术http://www.52ij.com/jishu/ 首先需要弄清楚什么叫原型模式,或者说为什么要有原型模式,运用它会给我们带来什么或能解决什么问题?原型模式(Prototype)同抽象工厂模式同属于创建型模式,它主要关注于大量相同或相似对象的创建问题,应用原型模式就是先需要一个原对象,然后通过对原对象进行复制(克隆),来产生一个与原对象相同或相似的新对象.注意这里所说的对象相同不是指复制出来的副本对象与原对象是同

C#设计模式(6)——原型模式(Prototype Pattern)

原文:C#设计模式(6)--原型模式(Prototype Pattern) 一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这未免会增加创建类的复杂度和耗费更多的内存空间,因为这样在内存中分配了多个一样的类实例对象,然后如果采用工厂模式来创建这样的系统的话,随着产品类的不断增加,导致子类的数量不断增多,反而增加了系统复杂程度,所以在这里使用工厂模式来封装类创建过程并不合适,然而原型模式可以很好地解决这个

设计模式之八(原型模式)

原文:设计模式之八(原型模式) 前言 原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 结构图 Prototype,原型类,声明一个克隆自身的接口 ConcretePrototype1,ConcretePrototype2具体原型类,实现一个克隆自身的操作 Client,调用,让一个原型克隆自身从而创建一个新的对象 其实原型模式就是从一个对象再创建另外一个可定制的对象,而且不需知道任何创建的细节. 代码实现  Prototype原型类设计代码 public abstra

乐在其中设计模式(C#) - 原型模式(Prototype Pattern)

原文:乐在其中设计模式(C#) - 原型模式(Prototype Pattern)[索引页][源码下载] 乐在其中设计模式(C#) - 原型模式(Prototype Pattern) 作者:webabcd 介绍 用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象. 示例 有一个Message实体类,现在要克隆它. MessageModel using System;using System.Collections.Generic;using System.Text;namespac

大话设计模式之原型模式

       外国人把那京戏叫做"Beijing Opera " 没见过那五色的油彩楞往脸上画,四击头一亮相,(哇--)美极了妙极了,简直"ok"顶呱呱 ,蓝脸的多尔敦盗御马,红脸的关公战长沙 ,黄脸的典韦白脸的曹操 ,黑脸的张飞叫喳喳-- ,细心的小朋友,仔细区分就会发现,虽然每个京剧演员都不同,但基本上只具有几种脸型,长方形,圆形,细长,然后配上不同的妆容,胡子,眉毛,头饰,服装,有的再加点儿装饰物,就成了我们所看到的不同的演员角色,国粹和我们的编程有着什么样的

设计模式:原型模式(Prototype)

 原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.  举个例子: 1 原型(实际上是implements了Cloneable接口,进而重写clone()方法) public class ProtoType implements Cloneable { private String name; @Override public ProtoType clone() { try { return (ProtoType)super.clone(); } catch (Clone

C++设计模式之原型模式_C 语言

什么是原型模式? 在GOF的<设计模式:可复用面向对象软件的基础>中是这样说的:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.这这个定义中,最重要的一个词是"拷贝",也就是口头上的复制,而这个拷贝,也就是原型模式的精髓所在. 举一个最简单的例子来说明原型模式:记得上小学的时候,老师把需要做的课外习题写到黑板上,而下面的我们都要把这些题抄写到自己的本子上,回家做好,第二天交上来,也就是每道题,全班50个人,每个人都要抄写一遍.按照现在的时间理论来说,就是浪费

【秒懂设计模式】原型模式

 秒懂设计模式--原型模式 (五)原型模式 [官方定义]用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象,属于对象创建模式. [举例]在找工作的时候,通常需要我们的毕业证和学位证,但是我们一般不会把原件(原型实例)给到用人单位,而是会把原件复印(拷贝)几份,然后供用人单位使用. [Java代码] ①创建一个证书抽象类. package com.liyan.prototype; /** * 证书抽象类 * <p>Title: Certificate</p> * @au

iOS设计模式之原型模式

What is the 原型模式? 原型设计模式是通过一个原型拷贝的方式快速创建一个新的对象. 拷贝分为两种: 浅拷贝(同一个地址,不同的指针) 深拷贝(不同的地址,完全的独立) 二者区别在于是否生成新的一个地址 When using the 原型模型? 需要创建的对象应独立于其类型与创建方式. 要实例化的类是在运行时决定的. 不想要与产品层次相对应的工厂层次. 不同类的实例间的差异仅仅是状态的若干组合.因此复制相应数量的原型比手工实例化更加方便. 类不容易创建,比如每个组件可把其他组件作为子节