Skip to content

模板方法模式

定义一个算法的骨架,将一些步骤延迟到子类中实现。父类规定流程,子类决定细节!

适用的场景

想要固定一个处理过程的大致步骤,但允许其中的某些步骤由子类自行定义。 有重复代码可以抽象到父类,子类做差异化处理 希望子类只控制部分流程,而不是整个逻辑乱改!

举个例子:

  • 游戏中的角色AI行为流程(感知→判断→行动)

  • 游戏加载流程(准备资源 → 进度显示 → 场景跳转)

  • 数据导出(准备 → 格式转换 → 保存)

和抽象类以及接口的区别是,模板方法不光规定了”要做什么“,还规定了执行顺序,子类只需要实现细节,不用管流程

基本结构

  • AbstractClass(抽象类):定义算法骨架,有模板方法(非虚方法)

  • ConcreteClass(具体类):实现抽象步骤,完成自定义行为

示例

csharp
abstract class Cooking 
{
    public void MakeDish() 
    {
        Prepare();      // 准备食材
        Cook();         // 烹饪
        Serve();        // 上菜
    }

    protected abstract void Prepare();
    protected abstract void Cook();
    protected virtual void Serve() 
    {
        Console.WriteLine("装盘上桌啦~");
    }
}

class FriedRice : Cooking 
{
    protected override void Prepare() => Console.WriteLine("准备米饭和蛋~");
    protected override void Cook() => Console.WriteLine("炒啊炒啊~锅气满满!");
}

// 使用
var dish = new FriedRice();
dish.MakeDish();

/*
输出
准备米饭和蛋~🥚🍚  
炒啊炒啊~锅气满满!  
装盘上桌啦~🍽️
*/

GDScript示例

gdscript
class Cooking:

    func make_dish() -> void:
        prepare()
        cook()
        serve()

    func prepare():
        pass

    func cook():
        pass

    func serve():
        print("装盘上桌啦~")
        
class FriedRice extends Cooking:

    func prepare():
        print("准备米饭和蛋~")

    func cook():
        print("炒啊炒啊~锅气满满!")

# 使用
func _read():
    var dish = FriedRice.new()
    dish.make_dish()