原型模式:使用特定原型实例来创建特定种类的对象,并且通过拷贝原型来创建新的对象。
写在前面
假如在游戏中我们需要生成各种各样的怪物,我们需要一个孵化器,我们想到为每个怪物类型确定一个孵化器,如下图所示:
1 2 3
| graph LR Ghost --> GhostSpawner Demo --> DemoSpawner
|
:heavy_check_mark: 不难想到,我们可以抽象出怪物的基类对上面的结构进行优化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| public abstract class Monster { public int Hp { get; set; } public float Speed { get; set; } public abstract Monster Clone();
public override string ToString() { return $"Hp:{Hp} Speed:{Speed}"; } } class Ghost: Monster { public override Monster Clone() { return new Ghost(){Hp=base.Hp,Speed = base.Speed}; } }
class Spawner { private Monster _monster; public Spawner(Monster monster) { _monster = monster; }
public Monster SpawnerMonster() { return _monster.Clone(); } }
|
调用1 2 3 4 5
| var gh = new Ghost() {Hp = 45, Speed = 3.3f}; var spa = new Spawner(gh);
var en= spa.SpawnerMonster(); Console.WriteLine(en);
|
结论
关于这个模式,有一点比较优雅的是,它不仅克隆原型类,而且它也克隆了对象的状态。
基于这样的模板(原型),我们可以创建出类似的一系列对象。
:blue_book: Ps: 有兴趣的话可以去看看Self语言相信你会对原型,oop有新的认识——类并不是实现oop的唯一方法。
:book:OOP的特征是它将状态和行为结合得更紧密。
扩展
正是self基于原型的设计理念,诞生了现在大受欢迎的javascript;
正是self不断强化编译技术,虚拟机效率,现在的动态语言才能高效执行。