设计模式之原型模式

简介: <p><span style="font-family:KaiTi_GB2312; font-size:24px"><strong>一.引入</strong></span></p> <p><span style="font-family:KaiTi_GB2312; font-size:24px">小菜的问题:要把简历发到多家公司,简历的份数就必须足够。</span></p> <p><s

一.引入

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

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

二.解决过程

① 最初的写法:

 简历类:

<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>
从而达到我们想要的结果,如下图:



五.学习心得

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







目录
相关文章
|
2月前
|
设计模式 Java
设计模式之原型模式
设计模式之原型模式
|
4月前
|
设计模式
设计模式 | 原型模式
设计模式 | 原型模式
22 0
|
4月前
|
设计模式 缓存 前端开发
【设计模式】之原型模式
原型模式是一种常用的设计模式,它通过克隆现有对象来创建新对象,减少了重复代码并提高了性能。在前端开发中,原型模式常用于对象创建、数据共享和缓存管理等场景。然而,需要注意对共享状态的管理和克隆操作的复杂性。
42 0
|
7月前
|
设计模式 C++
设计模式之原型模式(C++)
设计模式之原型模式(C++)
|
9月前
|
设计模式 Java 数据库连接
从零玩转设计模式之原型模式
从零玩转设计模式之原型模式
40 0
|
9月前
|
设计模式 JavaScript 安全
【3W2H设计模式】- 原型模式
【3W2H设计模式】- 原型模式
190 0
|
10月前
|
设计模式
设计模式-原型模式
设计模式-原型模式
49 0
|
12月前
|
设计模式 消息中间件 算法
一起来学设计模式之原型模式
前言 目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~ 本节给大家讲一下设计模式中的原型模式,并结合实际业务场景给大家讲解如何使用~ 本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~ 原型模式 原型模式是一种创建型设计模式,它通过复制(克隆)已有对象的实例来创建新的对象实例,而无需调用构造函数。这种方式可以提高对象创建的效率,同时也可以避免对象构造函数中的复杂逻辑。
|
设计模式 Java uml
《设计模式》原型模式
《设计模式》原型模式
《设计模式》原型模式
|
设计模式 Java 关系型数据库
23种设计模式——原型模式
原型模式主要用于创建重复的对象,同时又能保证系统的性能。
79 0
23种设计模式——原型模式