zoukankan      html  css  js  c++  java
  • C#设计模式之原型模式

    原型模式:使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象

    分析:

    孙悟空:根据自己的形状复制(克隆)出多个身外身
    软件开发:通过复制一个原型对象得到多个与原型对象一模一样的新对象
     
     
    工作原理:将一个原型对象传给要发动创建的对象(即客户端对象),这个要发动创建的对象通过请求原型对象复制自己来实现创建过程
    创建新对象(也称为克隆对象)的工厂就是原型类自身,工厂方由负责复制原型对象的克隆方法来实现
    通过克隆方法所创建的对象是全新的对象,它们在内存中拥有新的地址,每一个克隆对象都是独立
    通过不同的方式对克隆对象进行修改以后,可以得到一系列相似但不完全相同的对象
     
    原型模式的结构
    原型模式包含以下3个角色:
    •Prototype(抽象原型类)
    •ConcretePrototype(具体原型类)
    •Client(客户类)
     
    浅克隆与深克隆
    浅克隆(Shallow Clone)当原型对象被复制时,只复制它本身和其中包含的值类型的成员变量,而引用类型的成员变量并没有复制
    深克隆(Deep Clone)除了对象本身被复制外,对象所包含的所有成员变量也将被复制
     
     
    案例:
    [Serializable]  //深克隆时需要将类标记为Serializable
    public class Person:ICloneable
    {
        public string CurrentEmployee { get; set; }
        public Member Member { get; set; }
        public Person()
        {
            this.CurrentEmployee = "admin";
            Member member = new Member();
            member.Id = 3;
            member.Name = "Mem";
            this.Member = member;
        }
        public object Clone()
        {
            return this.MemberwiseClone();
        }
        #region 静态方式创建对象
        private static Person _person;
        /// <summary>
        /// 静态构造函数,永远只运行一次
        /// </summary>
        static Person()
        {
            _person = new Person();
        }
        public static Person StaticClone()
        {
            return _person.MemberwiseClone() as Person;
        } 
        #endregion
    }
    [Serializable]
    public class Member
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    public class SerializeHelper
    {
        /// <summary>
        /// 序列化
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        public static string Serializable(object target)
        {
            using(MemoryStream stream=new MemoryStream())
            {
                new BinaryFormatter().Serialize(stream,target);
                return Convert.ToBase64String(stream.ToArray());
            }
        }
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="target"></param>
        /// <returns></returns>
        public static T Derializable<T>(string target)
        {
            byte[] targetArray = Convert.FromBase64String(target);
            using (MemoryStream stream = new MemoryStream(targetArray))
            { 
                return (T)(new BinaryFormatter().Deserialize(stream));
            }
        }
        /// <summary>
        /// 合并反序列化与序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static T DeepClone<T>(T t)
        {
            return Derializable<T>(Serializable(t));
        }
    }

    调用:

    //浅表克隆,原来创建的对象值会改变
    Person p = new Person();
    Person p1 = p.Clone() as Person;
    p1.CurrentEmployee = "user";
    p1.Member.Id = 1;
    p1.Member.Name = "pp1";
    //深度克隆,原来创建的对象值不会改变
    Person p2 = p.Clone() as Person;
    Person p3 = SerializeHelper.Derializable<Person>(SerializeHelper.Serializable(p2));
    //或者简写
    //Person p3 = SerializeHelper.DeepClone<Person>(p2);
    p3.Member.Id = 6;
    p3.Member.Name = "dd3";
    Console.Read();
  • 相关阅读:
    理解mipi协议【转】
    Using KernelShark to analyze the real-time scheduler【转】
    内核栈溢出【转】
    检测内核的堆栈溢出【转】
    gcc 编译 + 选项【转】
    service mysqld start 报错:service mysqld start 报错 090517 13:34:15 [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it. 090Can't open the mysql.plugin table. Please run mysql
    【推荐】MySQL Cluster报错及解决方法(不断更新中)
    MySQL Cluster 配置文件(config.ini)详解
    关于MySQL Cluster集群NoOfReplicas参数问题
    通过PHP current()函数获取未知字符键名数组第一个元素的值
  • 原文地址:https://www.cnblogs.com/genesis/p/6097528.html
Copyright © 2011-2022 走看看