zoukankan      html  css  js  c++  java
  • 设计模式之笔记--原型模式(Prototype)

    原型模式(Prototype)

    定义

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

    类图

    描述

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

    应用场景

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

        public class Course
        {
            public string Name { get; set; }
        }
    
        public abstract class AbstractStudent
        {
            public string Name { get; set; }
            public int Age { get; set; }
            public Course Course { get; set; }
    
            public abstract AbstractStudent Clone();
        }
    
        /// <summary>
        /// 浅拷贝
        /// </summary>
        public class Student : AbstractStudent
        {
            public override AbstractStudent Clone()
            {
                Student student = new Student();
                student.Name = base.Name;
                student.Age = base.Age;
                student.Course = base.Course;
    
                return student;
            }
        }

    输出:

    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:

        [Serializable]
        public class Course
        {
            public string Name { get; set; }
        }
    
        [Serializable]
        public abstract class AbstractStudent
        {
            public string Name { get; set; }
            public int Age { get; set; }
            public Course Course { get; set; }
    
            public abstract AbstractStudent Clone();
        }
    
        [Serializable]
        /// <summary>
        /// 深拷贝
        /// </summary>
        public class Student : AbstractStudent
        {
            public override AbstractStudent Clone()
            {
                using (Stream objectStream = new MemoryStream())
                {
                    IFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(objectStream, this);
                    objectStream.Seek(0, SeekOrigin.Begin);
                    return formatter.Deserialize(objectStream) as Student;
                }
            }
        }

    输出:

    student : Jim 20 C++

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

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

    浅拷贝和深拷贝的区别:

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

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

  • 相关阅读:
    C++教程_w3cschool
    C++教程|菜鸟教程
    C++编程兵书
    学习C++从入门到精通的的十本最经典书籍
    从大公司到创业公司,技术人转型怎样转变思路与处事之道?
    c# 与 c++ 交互
    c++ 使用vs2010调用 win32api
    Excel学习笔记
    Windows环境变量设置无效解决办法——DOS窗口设置环境变量
    MAVEN ERROR: unable to find valid certification path to requested target 解决办法
  • 原文地址:https://www.cnblogs.com/zhou-yi/p/5322386.html
Copyright © 2011-2022 走看看