设计模式之笔记--原型模式(Prototype)

原型模式(Prototype)

类图

描述

原型模式:

提供一个克隆自身的接口--Clone方法。

应用场景

定义一个学生类,包含一个值类型(int)的Age属性、两个引用类型Name(string)和Course属性。

    public class Course
    {
        public string Name { get; set; }
    }

    public class Student : ICloneable
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public Course Course { get; set; }

        public object Clone()
        {
            return this.MemberwiseClone();
        }
    }

        static void Main(string[] args)
        {
            string value = ConfigurationManager.AppSettings["prototypePattern"];
            Student student = (Student)Assembly.Load(value.Substring(0, value.IndexOf(‘.‘))).CreateInstance(value);
            student.Name = "Jim";
            student.Age = 20;
            student.Course = new Course() { Name = "C++" };
            Console.WriteLine("student:" + student.Name + "\t" + student.Age + "\t" + student.Course.Name);

            Console.WriteLine();
            Student student1 = (Student)student.Clone();
            student1.Name = "Tom";
            student1.Age = 21;
            student1.Course.Name = "C#";
            Console.WriteLine("student:" + student.Name + "\t" + student.Age + "\t" + student.Course.Name);
            Console.WriteLine("student1:" + student1.Name + "\t" + student1.Age + "\t" + student1.Course.Name);

            Console.WriteLine();
            student1.Course.Name = "Java";
            Console.WriteLine("student:" + student.Name + "\t" + student.Age + "\t" + student.Course.Name);
            Console.WriteLine("student1:" + student1.Name + "\t" + student1.Age + "\t" + student1.Course.Name);
        }

输出:

student:Jim 20 C++

student:Jim 20 C#
student1:Tom 21 C#

student:Jim 20 Java
student1:Tom 21 Java

从打印的结果可以看出,给原对象student拷贝一个新的student1对象并给student1属性赋值之后,原对象student的Age和Name没变,CourseName却变了。原因是拷贝之后,student把student1的Age和Name复制了一份,而student1的Course依然指向student的Course地址,所以,当student1的CourseName改变时,student的CourseName也随之改变,这就是浅拷贝。

但是在实际应用中,往往不希望发生这样的事情,也就是不能因为拷贝对象发生变化而影响到原对象。原因很简单,不能因为Tom选了C#这门课就要求Jim也必须把已经选的C++这门课改成C#。要解决这个问题,就需要拷贝一个全新的对象,即深拷贝。

下面把Student类和Course类小改一下,通过序列化和反序列化来创建一个全新的student:

    [Serializable]
    public class Course
    {
        public string Name { get; set; }
    }

    [Serializable]
    public class Student : ICloneable
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public Course Course { get; set; }

        public object Clone()
        {
            using (Stream objectStream = new MemoryStream())
            {
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(objectStream, this);
                objectStream.Seek(0, SeekOrigin.Begin);
                return formatter.Deserialize(objectStream);
            }
        }
    }

输出:

student:Jim 20 C++

student:Jim 20 C++
student1:Tom 21 C#

student:Jim 20 C++
student1:Tom 21 Java

浅拷贝和深拷贝的区别:

浅拷贝:对值类型和string类型直接拷贝,对引用类型共用同一个指针;两个对象之间存在耦合;

深拷贝:给对象拷贝一个全新的对象,两个对象之间的耦合度为0。

时间: 2024-11-05 19:01:23

设计模式之笔记--原型模式(Prototype)的相关文章

设计模式 笔记 原型模式 prototype

//---------------------------15/04/07---------------------------- //prototype 原型模式--对象创建型模式 /* 1:意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 2:动机: 3:适用性: 1>当一个系统应该独立于它的产品创建.构成和表示时 2>当要实例化的类是在运行时刻制定时,例如通过动态装载 3>为了避免创建一个与产品类层次平行的工厂类层次时 4>当一个类的实例只能有几个不同状

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

原型模式:使用原型实例来指定创建对象的种类,并通过拷贝这个对象的值来创建新的对象. Specify the kind of objects to create using a prototypical instance, and create new objects by copying this prototype. UML图: 主要包括 Prototype:定义了一个包含克隆自身的接口 ConcretePrototype:具体的原型类,实现了克隆自身函数的类 Client:通过一个具体的原型

【大话设计模式读书笔记——原型模式】

原型模式 原型模式是创建型模式的一种,其特点在于通过"复制"一个已经存在的实例来返回新的实例,而不是新建实例.被复制的实例就是我们所称的"原型",这个原型是可定制的. 原型模式多用于创建复杂的或者耗时的实例,因为这种情况下,复制一个已经存在的实例使程序运行更高效:或者创建值相等,只是命名不一样的同类数据. /// <summary> /// 简历类 /// </summary> public class Resume : ICloneable

设计模式学习笔记--原型模式

1 using System; 2 3 namespace Prototype 4 { 5 /// <summary> 6 /// 作者:bzyzhang 7 /// 时间:2016/5/24 19:46:36 8 /// 博客地址:http://www.cnblogs.com/bzyzhang/ 9 /// WorkExperience说明:本代码版权归bzyzhang所有,使用时必须带上bzyzhang博客地址 10 /// </summary> 11 public class

设计模式学习笔记——原型模式

1.特点:在初始化信息不发生变化时考虑. 2.概念:通过复制一个已经存在的实例来创建一个新的实例.被复制的实例被称为原型,这个原型是可定制的. 3.类图: 4.程序实现: /// <summary> /// 实现了ICloneable接口的简历类 /// </summary> public class Resume:ICloneable { public Resume() { mWorkExperience = new WorkExperience(); } private str

[工作中的设计模式]原型模式prototype

一.模式解析 提起prototype,最近看多了js相关的内容,第一印象首先是js的原型 var Person=function(name){ this.name=name; } Person.prototype.run=function(){ alert(this.name+" is running"; } 此处的原型是js的特殊定义,在原型上定义的属性和方法所有的类进行共享. 不过设计模式中的原型模式指的是:将已有的对象作为原型,拷贝出一份具有相同属性的新的对象. 模式定义为:原型

谈谈设计模式~原型模式(Prototype)

返回目录 原型模式是创建型模式的一种,其特点在于通过“复制”一个已经存在的实例来返回新的实例(clone),而不是新建(new)实例.被复制的实例就是我们所称的“原型”,这个原型是可定制的. 原型模式多用于创建复杂的或者耗时的实例,因为这种情况下,复制一个已经存在的实例使程序运行更高效:或者创建值相等,只是命名不一样的同类数据. 从原型模式的概念中,我们可以看到,在这个模式里,拷贝是个很重要的概念,即在不创建对象的情况下,返回一个已有对象,这就是拷贝去实现的,在面向对象的编程世界里,拷贝分为浅拷

二十四种设计模式:原型模式(Prototype Pattern)

原型模式(Prototype Pattern) 介绍用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象. 示例有一个Message实体类,现在要克隆它. MessageModel using System; using System.Collections.Generic; using System.Text; namespace Pattern.Prototype { /// <summary> /// Message实体类 /// </summary> publi

设计模式学习05—原型模式

一.动机与定义 之前学习原型模式一直以为原型模式目的是为了方便的创建相同或相似对象,用复制对象的方式替换new的方式,还研究了深克隆和浅克隆.最近仔细看了GOF的设计模式,发现原型模式的本意并不仅仅是复制对象这么简单. 复制对象确实是一方面,当我们需要大量相似,甚至相同对象的时候,除了一个个的new之外,还可以根据一个原型,直接复制出更多的对象.但是如果把原型模式认为只是复制对象这么简单就错了. 创建型模式主要讲如何创建对象,通常包含何时创建,谁来创建,怎么创建等.GOF书里面写的意图是,用原型