在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。
如何应对这种变化?如何向“客户程序(使用这些对象的程序)”隔离出“这些易变对象”,从而使得“依赖这些易变对象的客户程序”不随着需求改变而改变?
意图:
使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。
出自:《设计模式》GoF
Prototype模式的几个要点:
1、Prototype模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些“易变类”拥有“稳定的接口”。
2、Prototype模式对于“如何创建易变类的实体对象”采用“原型克隆”的方法来做,它使得我们可以非常灵活地动态创建“拥有某些稳定接口”的新对象,所需工作仅仅是注册一个新类的对象(即原型),然后在任何需要的地方不断地Clone。
3、Prototype模式中的Clone方法可以利用.NET中的Object类的MemberwiseClone()方法(浅拷贝)或者序列化(深拷贝)来实现。
稳定部分:
1using System;
2
3namespace prototype
4{
5 /// <summary>
6 /// NormalActor 的摘要说明。
7 /// </summary>
8 public abstract class NormalActor
9 {
10 public abstract NormalActor Clone();
11 public abstract void Do();
12 }
13
14 public abstract class FlyActor
15 {
16 public abstract FlyActor Clone();
17 public abstract void Do();
18 }
19
20 public abstract class WaterActor
21 {
22 public abstract WaterActor Clone();
23 public abstract void Do();
24 }
25
26 public class GameSystem
27 {
28 NormalActor normalActor;
29 FlyActor flyActor;
30 WaterActor waterActor;
31
32 public GameSystem(NormalActor normalActor, FlyActor flyActor, WaterActor waterActor)
33 {
34 this.normalActor = normalActor;
35 this.flyActor = flyActor;
36 this.waterActor = waterActor;
37 }
38
39 public void Run()
40 {
41 NormalActor normalActor1 = normalActor.Clone();
42 NormalActor normalActor2 = normalActor.Clone();
43
44 FlyActor flyActor1 = flyActor.Clone();
45 FlyActor flyActor2 = flyActor.Clone();
46
47 WaterActor waterActor1 = waterActor.Clone();
48 WaterActor waterActor2 = waterActor.Clone();
49
50 normalActor1.Do();
51 normalActor2.Do();
52 flyActor1.Do();
53 flyActor2.Do();
54 waterActor1.Do();
55 waterActor2.Do();
56
57 }
58 }
59}
60
2
3namespace prototype
4{
5 /// <summary>
6 /// NormalActor 的摘要说明。
7 /// </summary>
8 public abstract class NormalActor
9 {
10 public abstract NormalActor Clone();
11 public abstract void Do();
12 }
13
14 public abstract class FlyActor
15 {
16 public abstract FlyActor Clone();
17 public abstract void Do();
18 }
19
20 public abstract class WaterActor
21 {
22 public abstract WaterActor Clone();
23 public abstract void Do();
24 }
25
26 public class GameSystem
27 {
28 NormalActor normalActor;
29 FlyActor flyActor;
30 WaterActor waterActor;
31
32 public GameSystem(NormalActor normalActor, FlyActor flyActor, WaterActor waterActor)
33 {
34 this.normalActor = normalActor;
35 this.flyActor = flyActor;
36 this.waterActor = waterActor;
37 }
38
39 public void Run()
40 {
41 NormalActor normalActor1 = normalActor.Clone();
42 NormalActor normalActor2 = normalActor.Clone();
43
44 FlyActor flyActor1 = flyActor.Clone();
45 FlyActor flyActor2 = flyActor.Clone();
46
47 WaterActor waterActor1 = waterActor.Clone();
48 WaterActor waterActor2 = waterActor.Clone();
49
50 normalActor1.Do();
51 normalActor2.Do();
52 flyActor1.Do();
53 flyActor2.Do();
54 waterActor1.Do();
55 waterActor2.Do();
56
57 }
58 }
59}
60
变化部分:
1using System;
2
3namespace prototype
4{
5 /// <summary>
6 /// NormalActorA 的摘要说明。
7 /// </summary>
8
9 public class NormalActorA : NormalActor
10 {
11 public NormalActorA()
12 {
13 Console.Write("NormalActorA"+"\n");
14 }
15 public override void Do()
16 {
17 Console.Write("NormalActorA Do \n");
18 }
19 public override NormalActor Clone()
20 {
21 //MemberwiseClone是object的一个受保护的方法,在子类可以调用它,得到一个浅拷贝,在原型模式里面一般要用深拷贝
22 //注意这里用return (NormalActorA)this.MemberwiseClone();也可以
23 return (NormalActor)this.MemberwiseClone();
24 }
25 }
26 public class FlyActorA : FlyActor
27 {
28 public FlyActorA()
29 {
30 Console.Write("FlyActorA"+"\n");
31 }
32 public override FlyActor Clone()
33 {
34 return (FlyActor)this.MemberwiseClone();
35 }
36 public override void Do()
37 {
38 Console.Write("FlyActorA Do \n");
39 }
40 }
41 public class WaterActorA : WaterActor
42 {
43 public WaterActorA()
44 {
45 Console.Write("WaterActorA"+"\n");
46 }
47 public override WaterActor Clone()
48 {
49 return (WaterActor)this.MemberwiseClone();
50 }
51 public override void Do()
52 {
53 Console.Write("WaterActorA Do \n");
54 }
55 }
56}
57
58
2
3namespace prototype
4{
5 /// <summary>
6 /// NormalActorA 的摘要说明。
7 /// </summary>
8
9 public class NormalActorA : NormalActor
10 {
11 public NormalActorA()
12 {
13 Console.Write("NormalActorA"+"\n");
14 }
15 public override void Do()
16 {
17 Console.Write("NormalActorA Do \n");
18 }
19 public override NormalActor Clone()
20 {
21 //MemberwiseClone是object的一个受保护的方法,在子类可以调用它,得到一个浅拷贝,在原型模式里面一般要用深拷贝
22 //注意这里用return (NormalActorA)this.MemberwiseClone();也可以
23 return (NormalActor)this.MemberwiseClone();
24 }
25 }
26 public class FlyActorA : FlyActor
27 {
28 public FlyActorA()
29 {
30 Console.Write("FlyActorA"+"\n");
31 }
32 public override FlyActor Clone()
33 {
34 return (FlyActor)this.MemberwiseClone();
35 }
36 public override void Do()
37 {
38 Console.Write("FlyActorA Do \n");
39 }
40 }
41 public class WaterActorA : WaterActor
42 {
43 public WaterActorA()
44 {
45 Console.Write("WaterActorA"+"\n");
46 }
47 public override WaterActor Clone()
48 {
49 return (WaterActor)this.MemberwiseClone();
50 }
51 public override void Do()
52 {
53 Console.Write("WaterActorA Do \n");
54 }
55 }
56}
57
58
主程序:
1using System;
2
3namespace prototype
4{
5 /// <summary>
6 /// Class1 的摘要说明。
7 /// </summary>
8 class Class1
9 {
10 /// <summary>
11 /// 应用程序的主入口点。
12 /// </summary>
13 [STAThread]
14 static void Main(string[] args)
15 {
16 //变化点
17 //这里的参数是一个组合,比起其它创建型的模式要灵活一点
18 GameSystem g = new GameSystem(new NormalActorA(),new FlyActorA(),new WaterActorA());
19 //GameSystem g = new GameSystem(new NormalActorB(),new FlyActorB(),new WaterActorB());
20 //g.Run(new NormalActorA(),new FlyActorA(),new WaterActorA());
21 g.Run();
22 Console.ReadLine();
23
24 }
25 }
26}
27
2
3namespace prototype
4{
5 /// <summary>
6 /// Class1 的摘要说明。
7 /// </summary>
8 class Class1
9 {
10 /// <summary>
11 /// 应用程序的主入口点。
12 /// </summary>
13 [STAThread]
14 static void Main(string[] args)
15 {
16 //变化点
17 //这里的参数是一个组合,比起其它创建型的模式要灵活一点
18 GameSystem g = new GameSystem(new NormalActorA(),new FlyActorA(),new WaterActorA());
19 //GameSystem g = new GameSystem(new NormalActorB(),new FlyActorB(),new WaterActorB());
20 //g.Run(new NormalActorA(),new FlyActorA(),new WaterActorA());
21 g.Run();
22 Console.ReadLine();
23
24 }
25 }
26}
27