C#学习笔记-原型模式
题目:编写基本的简历。
实现:
创建基本的Resume类,然后主函数通过实例化Resume来写简历即可。
Resume类:
1 class Resume 2 { 3 private string name; 4 private string sex; 5 private string age; 6 private string timeArea; 7 private string company; 8 9 public Resume(string name) 10 { 11 this.name = name; 12 } 13 14 //设置个人信息 15 public void SetPersonalInfo(string sex,string age) 16 { 17 this.age = age; 18 this.sex = sex; 19 } 20 21 public void SetWorkExperience(string timeArea,string company) 22 { 23 this.timeArea = timeArea; 24 this.company = company; 25 } 26 27 public void Show() 28 { 29 Console.WriteLine("{0} {1} {2} ", name, sex, age); 30 Console.WriteLine("工作经历:{0} {1} ", timeArea, company); 31 } 32 }
View Code
主函数:
1 static void Main(string[] args) 2 { 3 //每写一份简历就实例化一次Resume,写一百分相同的简历也要实例化一百次 4 //且如果写错了一个词就得修改同样次数的简历 5 Resume a = new Resume("Taylor"); 6 a.SetPersonalInfo("女", "28"); 7 a.SetWorkExperience("1999-2008", "QWE"); 8 a.Show(); 9 10 Resume b = new Resume("Selena"); 11 b.SetPersonalInfo("女", "28"); 12 b.SetWorkExperience("1999-2008", "MNB"); 13 b.Show(); 14 15 //Console.Read(); 16 17 //这是传引用,而不是传值,这样如同在c1和b1的纸张上写着:简历在a1处,并没有实际的内容 18 Resume a1 = new Resume("Taylor"); 19 a1.SetPersonalInfo("女", "28"); 20 a1.SetWorkExperience("1999-2008", "QWE"); 21 a1.Show(); 22 23 Resume b1 = a1; 24 Resume c1 = a1; 25 26 b1.Show(); 27 c1.Show(); 28 29 Console.Read(); 30 }
View Code
题目延伸1:如果我们现在批量打印简历,如果用上面的方法就得每写一份简历都得实例化一次,且如果简历的某种信息输入错误,那么我们就得修改同样次数的简历,这就使工作量变得巨大了。
解析:
这时我们就需要引进原型模式(Prototype)
原型模式(Prototype),用原型实例指定创建对象的种类,并且 通过拷贝这些原型创建新的对象。
原型模式的范例:(这个例子是书上看来的,敲完了,看完了,还是理解的不是特别清楚,我的理解还是比较适合实例一点,这个真的看得无力......)
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 ConcretePrototypel p1 = new ConcretePrototypel("I"); 6 ConcretePrototypel c1 = (ConcretePrototypel)p1.Clone(); 7 Console.WriteLine("Cloned: {0}", c1.Id); 8 9 ConcretePrototypel2 p2 = new ConcretePrototypel2("II"); 10 ConcretePrototypel2 c2 = (ConcretePrototypel2)p2.Clone(); 11 Console.WriteLine("Cloned: {0}", c2.Id); 12 13 // Wait for user 14 Console.Read(); 15 16 } 17 } 18 19 //原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。 20 abstract class Prototype 21 { 22 private string id; 23 24 public Prototype(string id) 25 { 26 this.id = id; 27 } 28 29 public string Id 30 { 31 get 32 { 33 return id; 34 } 35 } 36 37 public abstract Prototype Clone(); 38 } 39 40 41 class ConcretePrototypel:Prototype 42 { 43 public ConcretePrototypel(string id):base(id) 44 { 45 } 46 47 public override Prototype Clone() 48 { 49 //创建当前对象的浅表副本。方法是创建一个新对象,然后将当前对象的 50 //非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。 51 //如果字段是引用类型,则复制引用但不复制引用的对象。 52 //因此,原始对象及副本引用同一对象。 53 return (Prototype)this.MemberwiseClone(); 54 } 55 } 56 57 58 class ConcretePrototypel2 : Prototype 59 { 60 public ConcretePrototypel2(string id) : base(id) 61 { 62 } 63 64 public override Prototype Clone() 65 { 66 // 67 // 摘要: 68 // 创建当前 System.Object 的浅表副本。 69 // 70 // 返回结果: 71 // 当前 System.Object 的浅表副本。 72 return (Prototype)this.MemberwiseClone(); 73 } 74 }
View Code
实现:
Resume类:
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);}public object Clone(){/*** MemberwiseClone()方法:* 如果字段是值类型,则对该字段执行逐位复制,* 如果字段是引用类型,则复制引用但不复制引用的对象* 因此,原始对象及其复本引用同一对象* * 换句话就是,* 如果Resume中有对象引用,那么引用的对象数据是不会被克隆过来的*/return (object)this.MemberwiseClone();}}
View Code
主函数:
1 static void Main(string[] args) 2 { 3 /**一般在初始化的信息不发生变化的情况下, 4 * 克隆是最好的办法 5 * 这既隐藏了对象创建的细节,又对性能是大大的提高 6 * 7 * 不用重新初始化对象,而是动态地获取对象运行时的状态 8 */ 9 Resume a = new Resume("taylor"); 10 a.SetPersonalInfo("女", "28"); 11 a.SetWorkExperience("1999-2008", "YUT"); 12 13 Resume b = (Resume)a.Clone(); 14 b.SetWorkExperience("1998-2006", "RTE"); 15 16 Resume c = (Resume)a.Clone(); 17 c.SetPersonalInfo("男", "30"); 18 19 a.Display(); 20 b.Display(); 21 c.Display(); 22 23 Console.Read(); 24 }
View Code
题目延伸2:如果在简历中设置一个“工作经历”类,其中包括“时间区间”和“公司名称”等属性,简历直接调用这个对象即可。
解析:
如果按照正常的方式书写就会发现,中途如果修改了工作经历的信息,那么所有的简历工作经历都变成了最后一次修改的信息。
对于工作经历里的参数而言,他们属于静态的参数值,故此他们的最后显示会根据最后的输入值。
1 static void Main(string[] args) 2 { 3 Resume a = new Resume("Taylor"); 4 a.SetPersonalInfo("28", "女"); 5 a.SetWorkExperience("1999-2008", "UIO"); 6 7 Resume b = (Resume)a.Clone(); 8 b.SetWorkExperience("1990-2000", "QWE"); 9 b.SetPersonalInfo("24", "男"); 10 11 Resume c = (Resume)a.Clone(); 12 c.SetPersonalInfo("30", "男"); 13 c.SetWorkExperience("1000-2000", "QWE"); 14 //最后c的将work.WorkDate设置为了"1000-2000",work.Company设置为了"QWE" 15 //故此b的工作经历显示也如同c一般了,a也同理 16 //==>“浅复制” 17 18 a.Display(); 19 b.Display(); 20 c.Display(); 21 22 Console.Read(); 23 } 24 25 class Resume:ICloneable 26 { 27 private string name; 28 private string sex; 29 private string age; 30 31 private WorkExperience work; 32 33 34 public Resume(string name) 35 { 36 this.name = name; 37 work = new WorkExperience();//实例化 38 } 39 40 public void SetPersonalInfo(string age,string sex) 41 { 42 this.age = age; 43 this.sex = sex; 44 } 45 46 public void SetWorkExperience(string timeArea,string company) 47 { 48 work.WorkDate = timeArea; 49 work.Company = company; 50 51 } 52 53 public void Display() 54 { 55 Console.WriteLine("{0} {1} {2}", name, sex, age); 56 Console.WriteLine("工作经历:{0} {1}", work.WorkDate, work.Company); 57 } 58 59 public object Clone() 60 { 61 return (object)this.MemberwiseClone(); 62 } 63 } 64 65 class WorkExperience 66 { 67 private string workDate; 68 69 public string WorkDate 70 { 71 get 72 { 73 return workDate; 74 } 75 76 set 77 { 78 workDate = value; 79 } 80 } 81 82 private string company; 83 84 public string Company 85 { 86 get 87 { 88 return company; 89 } 90 91 set 92 { 93 company = value; 94 } 95 } 96 }
View Code
所以这就涉及到了MemberwiseClone()方法,“浅复制”和“深复制”问题了。
MemberwiseClone():如果字段是值类型,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其副本引用同意对象。
=>换句话就是,简历中所包含的对象引用,其引用的对象数据是不会被克隆过来的。
MemberwiseClone()就是“浅复制”:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。
“深复制”:把引用对象的变量指向复制过的新对象,而不是原来的被引用的对象。
实现:
1 class Resume:ICloneable 2 { 3 private string name; 4 private string age; 5 private string sex; 6 7 private WorkExperience work; 8 public Resume(string name) 9 { 10 this.name = name; 11 work = new WorkExperience(); 12 } 13 14 /// <summary> 15 /// 私有函数 16 /// 将工作经历克隆过来 17 /// </summary> 18 /// <param name="work"></param> 19 private Resume(WorkExperience work) 20 { 21 this.work = (WorkExperience)work.Clone(); 22 } 23 24 public void SetPersonalInfo(string age,string sex) 25 { 26 this.age = age; 27 this.sex = sex; 28 } 29 30 public void SetWorkExperience(string workDate,string company) 31 { 32 work.Company = company; 33 work.WorkDate = workDate; 34 } 35 36 public void Display() 37 { 38 Console.WriteLine("{0} {1} {2}", name, sex, age); 39 Console.WriteLine("工作经历:{0} {1}", work.WorkDate, work.Company); 40 } 41 42 43 public object Clone() 44 { 45 //调用私有的构造方法,让“工作经历”克隆完成 46 //然后再给这个“简历”对象的相关字段赋值 47 //最终返回一个深复制的简历对象 48 Resume obj = new Resume(this.work); 49 obj.name = this.name; 50 obj.sex = this.sex; 51 obj.age = this.age; 52 53 return obj; 54 } 55 } 56 57 class WorkExperience : ICloneable 58 { 59 private string workDate; 60 private string company; 61 62 public string WorkDate 63 { 64 get 65 { 66 return workDate; 67 } 68 69 set 70 { 71 workDate = value; 72 } 73 } 74 75 public string Company 76 { 77 get 78 { 79 return company; 80 } 81 82 set 83 { 84 company = value; 85 } 86 } 87 88 public object Clone() 89 { 90 return (object)this.MemberwiseClone(); 91 } 92 }
View Code
注:文中所有代码及知识点均来自于《大话设计模式》,本人属于边学边看边敲代码边总结的阶段。
转载于:https://www.cnblogs.com/Aries-rong/p/7607573.html
C#学习笔记-原型模式相关推荐
- JavaScript --- [学习笔记] 原型模式
说明 接JavaScript - > [学习笔记]观察者模式 & 理解对象 & 工厂模式 & 构造函数模式 上一篇构造函数模式创建的实例,不同实例的同一个方法是不相等的, ...
- 设计模式学习笔记-原型模式
一.概述 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象: 二.模式中的角色 Prototype:声明一个克隆自身的接口: ConcretePrototype:实现一个克隆自身的操作: ...
- 设计模式学习笔记——原型(Prototype)框架
设计模式学习笔记--原型(Prototype)框架 @(设计模式)[设计模式, 原型模式, prototype] 设计模式学习笔记原型Prototype框架 基本介绍 原型案例 类图 实现代码 Pro ...
- 设计模式 - 学习笔记 - 工厂模式Factory Pattern
设计模式 - 学习笔记 - 工厂模式Factory Pattern 1. 简单工厂 1.1 应用场景 1.2 UML 1.3 优劣分析 好处 缺点 1.4 代码示例 抽象产品 AbstractProd ...
- x86架构学习笔记实模式
8086是Inter公司的第一款16微处理器,诞生于1978年,8086在市场上获得了巨大成功,所以后期芯片都兼容它. 8086有8个16位通用寄存器 AX,BX,CX,DX,SI,DI,BP,SP其 ...
- flutter学习笔记-MVVM模式学习解决报错
最近学习flutter,进行mvvm模式学习的时候,报了一错: [VERBOSE-2:ui_dart_state.cc(199)] Unhandled Exception: Error: Could ...
- JS学习笔记 原型链和利用原型实现继承
原型链 原型链是一种关系,实例对象和原型对象之间的关系,关系是通过原型(__proto__)来联系的 实例对象中有__proto__,是对象,叫原型,不是标准的属性,浏览器使用,并且有的游览器不支持 ...
- APM飞控学习笔记——自动模式下一分钟自动降落
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.自动模式简介 二.添加自动降落功能 1.飞控主循环调用逻辑 2.功能添加 总结 前言 APM是一款功能齐全的开源多 ...
- 设计模式学习笔记-中介模式
概述: ...
最新文章
- 使用Python部署机器学习模型的10个实践经验
- SLF4j+LOG4j
- 敏捷到底有没有带来新的东西?
- c++ 向量的值逆序输出_C++中vector的常用方法
- 在业务层实现校验请求参数
- MYSQL 查看表上索引的 1 方法
- vs生成qt moc文件
- CSS中盒子模型、嵌套盒子中垂直外边距塌陷问题解决方案、标准盒模型、怪异盒模型
- Chrome 开发工具 Workspace 使用
- 雷曼java_java入门(2)--数据类型
- 利用圆解一元二次方程
- win10风格美化以及新建系统后优化
- 第19节贝叶斯原理及实例
- 高斯光束的简单matlab仿真
- 「津津乐道播客」#342 编码人声:跟「老」程序员们聊聊编程的历史与未来
- worldpress自定义页面
- 直角三角形 纪中 1385 数学_斜率
- Hotkeycontrol录制宏
- 西门子 PLC S7单边通信
- 2022数学建模国赛B题思路分析
热门文章
- 制作CAB自解压文件的工具——IExpress
- vue-cli4 关闭 eslint 提示 解决‘xx‘ is defined but never used
- Java - 初探贪心算法(纸币找零,背包问题)
- 【Python笔记】元组的用法
- The requested lisk key xxx could not be resolved as a collection type.
- Windows域控 批量设置用户下次登录 修改密码【全域策略生效】
- docker容器内安装ifconfig netstat ping vim 等测试工具的方法
- TB创建公式应用dll失败 请检查用户权限,终极解决方案
- android 判断listview是否为空,ListView为空时显示空视图
- java中减法命令_java中减法和乘法的性能比较