设计模式-创建型模式:原型模式PrototypeModel
原型模式:不重复调用构造函数,在不通过构造函数的情况下,创建一个对象出来
通过克隆的方式创建对象,让整个程序使用的是不同的对象
应用案例:Sql局部更新
原型模式分为 浅表克隆和深表克隆
浅表克隆代码:
Lol类:
class Lol{private Lol(){Console.WriteLine("构造函数 执行一次");}private static Lol loler = null;static Lol(){loler = new Lol();}public string Name { get; set; }public static Lol CreateInstance(){Lol lolers = (Lol)loler.MemberwiseClone();//克隆一个新的对象return lolers;}}
调用
Lol loler1 = Lol.CreateInstance();loler1.Name = "发条魔灵";Lol loler2 = Lol.CreateInstance();loler2.Name = "锤石";Console.WriteLine("第一英雄是{0}********第二个英雄是{1}",loler1.Name,loler2.Name);Console.Read();
结果:
但是 这种克隆方式 是有缺陷的,如下所示:
添加以下代码:
添加一个类 表示英雄信息
public class Xx{public int ID { get; set; }public string Xb { get; set; }}
修改以前的Lol类
class Lol{private Lol(){Console.WriteLine("构造函数 执行一次");}private static Lol loler = null;static Lol(){loler = new Lol();loler.Xxs = new Xx(){ID = 3,Xb = "不男不女"};}public string Name { get; set; }public Xx Xxs { get; set; }public static Lol CreateInstance(){Lol lolers = (Lol)loler.MemberwiseClone();//克隆一个新的对象return lolers;}}
调用:
Lol loler1 = Lol.CreateInstance();loler1.Name = "发条魔灵";Lol loler2 = Lol.CreateInstance();loler2.Name = "锤石";Console.WriteLine("第一英雄是{0}********第二个英雄是{1}",loler1.Name,loler2.Name);Console.WriteLine("**********************原型模式 浅表克隆缺点***************************");loler1.Xxs.ID = 1;loler1.Xxs.Xb = "女";Console.WriteLine("{0}的ID是{1}、性别是{2}",loler1.Name,loler1.Xxs.ID,loler1.Xxs.Xb);Console.WriteLine("下面给loler2的Xxs赋值");loler2.Xxs.ID = 2;loler2.Xxs.Xb = "男";Console.WriteLine("{0}的ID是{1}、性别是{2}", loler2.Name, loler2.Xxs.ID, loler2.Xxs.Xb);Console.WriteLine("再看一下 修改完loler2后的loler1中Xxs的值");Console.WriteLine("{0}的ID是{1}、性别是{2}", loler1.Name, loler1.Xxs.ID, loler1.Xxs.Xb);Console.Read();
执行结果
第二次给Xxs里面内容赋值后,会影响到1里面的 内容,因为Xxs是一个引用类型,指向的是一块内存空间,所以修改之后,1和2都会一起修改
为了解决上述问题 通过序列化推出 深表克隆
通过对克隆出来的对象进行序列化后再反序列化 会得到一个全新的对象
前提记得给需要序列化的加特性修饰 [Serializable]
新增序列化方法
public class SerialzeHelper{/// <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));}}}
方法添加 [Serializable]修饰
调用:
static void Main(string[] args){Lol loler1 = Lol.CreateInstance();loler1.Name = "发条魔灵";Lol loler2 = Lol.CreateInstance();loler2.Name = "锤石";Console.WriteLine("第一英雄是{0}********第二个英雄是{1}",loler1.Name,loler2.Name);Console.WriteLine("**********************原型模式 浅表克隆缺点***************************");loler1.Xxs.ID = 1;loler1.Xxs.Xb = "女";Console.WriteLine("{0}的ID是{1}、性别是{2}",loler1.Name,loler1.Xxs.ID,loler1.Xxs.Xb);Console.WriteLine("下面给loler2的Xxs赋值");loler2.Xxs.ID = 2;loler2.Xxs.Xb = "男";Console.WriteLine("{0}的ID是{1}、性别是{2}", loler2.Name, loler2.Xxs.ID, loler2.Xxs.Xb);Console.WriteLine("再看一下 修改完loler2后的loler1中Xxs的值");Console.WriteLine("{0}的ID是{1}、性别是{2}", loler1.Name, loler1.Xxs.ID, loler1.Xxs.Xb);Console.WriteLine("**********************深表克隆***************************");Lol loler3 = SerialzeHelper.Derializable<Lol>(SerialzeHelper.Serializable(loler2));Console.WriteLine("下面修改loler3的值");loler3.Xxs.ID = 99;loler3.Xxs.Xb = "很奇怪";Console.WriteLine("{0}的ID是{1}、性别是{2}", loler1.Name, loler1.Xxs.ID, loler1.Xxs.Xb);Console.WriteLine("{0}的ID是{1}、性别是{2}", loler2.Name, loler2.Xxs.ID, loler2.Xxs.Xb);Console.WriteLine("{0}的ID是{1}、性别是{2}", loler3.Name, loler3.Xxs.ID, loler3.Xxs.Xb);Console.Read();}
结果:
最后3的修改 并没有影响1和2的值
个人学习笔记 可添加我QQ 1219958536 共同探讨 加好友的时候记得备注CSDN
设计模式-创建型模式:原型模式PrototypeModel相关推荐
- 设计模式(创建型)之建造者模式(Builder Pattern)
PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbob ...
- Java设计模式之创建型:原型模式
一.什么是原型模式: 原型模式主要用于对象的创建,使用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.UML类图如下: 原型模式的核心是就是原型类 Prototype,Prototype ...
- java设计模式——创建型之建造者模式
自大学课程初识设计模式以来,就越发觉得有必要系统学习一下设计模式. 刚好在实习前准备期间课比较少,抽出一点时间整理一下记一些笔记,复制粘贴比较多. 笔记比较适合学习过设计模式的同学. Builder ...
- Java设计模式之创建型:建造者模式
一.什么是建造者模式: 建造者模式将复杂产品的创建步骤分解在在不同的方法中,使得创建过程更加清晰,从而更精确控制复杂对象的产生过程:通过隔离复杂对象的构建与使用,也就是将产品的创建与产品本身分离开来, ...
- 《设计模式详解》创建型模式 - 原型模式
原型模式 4.3 原型模式 4.3.1 概述 4.3.2 结构 4.3.3 实现 4.3.4 案例 4.3.5 使用场景 4.3.6 扩展 - 深克隆 引用对象的浅克隆 实现 1:文件流 + 对象流 ...
- 设计模式-创建型模式-原型模式(Java)(创建重复对象)
目录 原型模式 1 介绍 2 实现 具体实现步骤 原型模式 原型模式(Prototype Pattern)是⽤于创建重复的对象,同时⼜能保证性能.这种类型的设计模式属于创建型模式,它提供了⼀种创建对象 ...
- JAVA设计模式 - 创建型模式总结
JAVA设计模式 - 单例模式 JAVA设计模式 - 工厂方法模式 JAVA设计模式 - 抽象工厂模式 JAVA设计模式 - 原型模式 JAVA设计模式 - 建造者模式 1 . 创建型模式的定义 顾名 ...
- GOF23设计模式-创建型模式4-原型模式
设计模式GOF23-原型模式 思考 原型模式 原型模式实现 克隆绵羊多利(浅拷贝) 克隆绵羊多利(深拷贝) 利用序列化和反序列化技术实现深克隆 何时使用? 测试new与clone创建对象效率 思考 克 ...
- 七大设计原则与设计模式(创建型模式、结构型模式、行为型模式)
七大设计原则 开闭原则.依赖倒置原则.单一职责原则.接口隔离原则.迪米特法则(最少知道原则).里氏替换原则.合成 (组合).聚合复用原则 开闭原则 定义: 一个软件实体如类.模块和函数应该对扩展开放, ...
- 设计模式(20):创建型-抽象工厂模式(Abstract Factory)
设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于 ...
最新文章
- shell学习(17)- shell中21的解释及输入输出重定向
- Cocos2D研究院之精灵与动画
- Kafka关键参数设置
- 【Git、GitHub、GitLab】十 将git仓库备份到本地
- 解决ora-00054 Oracle锁表问题
- scrapy 自动下载图片
- mysql数据库myisam_MySQL数据库修复方法(MyISAM/InnoDB)
- 闭包——抽象解释的简单注释
- 数学——对数公式log常识回顾
- selenium+python模拟键盘操作
- Web Directions South 2012的四个大创意
- SQL脚本得到Epicor客制化信息
- word公式编辑器输入斜体
- docker stop 失败处理方法
- 【0基础入门课程】实战入门柿饼UI,带你实现动感汽车仪表盘、APP Store等
- Canvas实用库收藏
- 大数据技术之Spark(三) SparkStreaming
- mock测试 (mock-test 模仿测试)
- ppt资源的拖动插入方法
- java文件切割_Java实现文件切割拼接的实现代码