Skip to content

原型模式

用原型实例指定创建对象的种类,并且通过复制这个原型来创建新的对象。

适合的场景

有些对象:

  • 创建成本高(初始化超复杂 or 代价大)

  • 创建速度慢(比如加载大量资源或远程数据)

  • 创建过程难以统一(组合、嵌套属性繁多)

这时你如果每次都手动 new + 设置属性,简直折磨自己

那就干脆先准备一个“模板对象”,每次复制一份就完事了

  • 对象创建成本高,但大多数内容都一样,只改少部分

  • 希望对象能“按当前状态”复制出一份

  • 游戏中需要批量生成大量类似对象(NPC、技能、弹幕等)

基本结构

  1. 抽象原型(通常是接口/基类,定义 clone 方法)

  2. 具体原型(实现 clone,返回当前对象的复制品)

  3. 使用者通过 clone() 获取副本,而不是自己 new

示例

csharp
// 抽象原型
public interface IPrototype<T>
{
    T Clone();
}

// 产品类
public class Enemy : IPrototype<Enemy>
{
    public string Type { get; set; }
    public int HP { get; set; }

    public Enemy Clone()
    {
        return (Enemy)this.MemberwiseClone(); // 浅拷贝
    }

    public void Show()
    {
        Console.WriteLine($"类型: {Type}, 血量: {HP}");
    }
}

// 使用
var prototype = new Enemy { Type = "Slime", HP = 100 };
var clone1 = prototype.Clone();
clone1.HP = 50;

prototype.Show(); // 类型: Slime, 血量: 100
clone1.Show();    // 类型: Slime, 血量: 50

MemberwiseClone() 是 C# 自带的浅拷贝方法,适合字段较简单时用。

如果对象中含有复杂结构(数组、引用类型等),可能要手动实现“深拷贝”。

GDScript 示例

gdscript
class Enemy:
    var type := ""
    var hp := 0

    func clone() -> Enemy:
        var copy = Enemy.new()
        copy.type = self.type
        copy.hp = self.hp
        return copy

    func show():
        print("类型: %s, 血量: %d" % [type, hp])
        
# 使用
func _ready():
    var proto = Enemy.new()
    proto.type = "骷髅兵"
    proto.hp = 150
    
    var copy = proto.clone()
    copy.hp = 80
    
    proto.show()  # 类型: 骷髅兵, 血量: 150
    copy.show()   # 类型: 骷髅兵, 血量: 80