题目:编写基本的简历。

实现:

创建基本的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#学习笔记-原型模式相关推荐

  1. JavaScript --- [学习笔记] 原型模式

    说明 接JavaScript - > [学习笔记]观察者模式 & 理解对象 & 工厂模式 & 构造函数模式 上一篇构造函数模式创建的实例,不同实例的同一个方法是不相等的, ...

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

    一.概述 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象: 二.模式中的角色 Prototype:声明一个克隆自身的接口: ConcretePrototype:实现一个克隆自身的操作: ...

  3. 设计模式学习笔记——原型(Prototype)框架

    设计模式学习笔记--原型(Prototype)框架 @(设计模式)[设计模式, 原型模式, prototype] 设计模式学习笔记原型Prototype框架 基本介绍 原型案例 类图 实现代码 Pro ...

  4. 设计模式 - 学习笔记 - 工厂模式Factory Pattern

    设计模式 - 学习笔记 - 工厂模式Factory Pattern 1. 简单工厂 1.1 应用场景 1.2 UML 1.3 优劣分析 好处 缺点 1.4 代码示例 抽象产品 AbstractProd ...

  5. x86架构学习笔记实模式

    8086是Inter公司的第一款16微处理器,诞生于1978年,8086在市场上获得了巨大成功,所以后期芯片都兼容它. 8086有8个16位通用寄存器 AX,BX,CX,DX,SI,DI,BP,SP其 ...

  6. flutter学习笔记-MVVM模式学习解决报错

    最近学习flutter,进行mvvm模式学习的时候,报了一错: [VERBOSE-2:ui_dart_state.cc(199)] Unhandled Exception: Error: Could ...

  7. JS学习笔记 原型链和利用原型实现继承

    原型链 原型链是一种关系,实例对象和原型对象之间的关系,关系是通过原型(__proto__)来联系的 实例对象中有__proto__,是对象,叫原型,不是标准的属性,浏览器使用,并且有的游览器不支持 ...

  8. APM飞控学习笔记——自动模式下一分钟自动降落

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.自动模式简介 二.添加自动降落功能 1.飞控主循环调用逻辑 2.功能添加 总结 前言 APM是一款功能齐全的开源多 ...

  9. 设计模式学习笔记-中介模式

    概述:                                                                                                 ...

最新文章

  1. 使用Python部署机器学习模型的10个实践经验
  2. SLF4j+LOG4j
  3. 敏捷到底有没有带来新的东西?
  4. c++ 向量的值逆序输出_C++中vector的常用方法
  5. 在业务层实现校验请求参数
  6. MYSQL 查看表上索引的 1 方法
  7. vs生成qt moc文件
  8. CSS中盒子模型、嵌套盒子中垂直外边距塌陷问题解决方案、标准盒模型、怪异盒模型
  9. Chrome 开发工具 Workspace 使用
  10. 雷曼java_java入门(2)--数据类型
  11. 利用圆解一元二次方程
  12. win10风格美化以及新建系统后优化
  13. 第19节贝叶斯原理及实例
  14. 高斯光束的简单matlab仿真
  15. 「津津乐道播客」#342 编码人声:跟「老」程序员们聊聊编程的历史与未来
  16. worldpress自定义页面
  17. 直角三角形 纪中 1385 数学_斜率
  18. Hotkeycontrol录制宏
  19. 西门子 PLC S7单边通信
  20. 2022数学建模国赛B题思路分析

热门文章

  1. 制作CAB自解压文件的工具——IExpress
  2. vue-cli4 关闭 eslint 提示 解决‘xx‘ is defined but never used
  3. Java - 初探贪心算法(纸币找零,背包问题)
  4. 【Python笔记】元组的用法
  5. The requested lisk key xxx could not be resolved as a collection type.
  6. Windows域控 批量设置用户下次登录 修改密码【全域策略生效】
  7. docker容器内安装ifconfig netstat ping vim 等测试工具的方法
  8. TB创建公式应用dll失败 请检查用户权限,终极解决方案
  9. android 判断listview是否为空,ListView为空时显示空视图
  10. java中减法命令_java中减法和乘法的性能比较