Skip to content

策略模式

把一个对象的“行为算法”提取出来,做成可替换的策略,让对象在运行时可以“挑一个”策略来用

适用的场景

  • 当你发现一堆 if/else/switch 在判断“用哪种算法”时!

  • 当你希望行为可切换、可扩展,又不想每次都改主类逻辑!

  • 当行为算法/规则经常变动,但主体对象逻辑不想动!

比如:

  • 不同排序策略(快排、冒泡、归并)

  • 不同攻击策略(近战、远程、魔法)

  • 不同定价策略(打折、满减、会员)

基本结构

  • Context(上下文):使用策略的对象,持有策略对象的引用

  • Strategy(策略):抽象策略接口,定义统一的行为函数

  • ConcreteStrategy(具体策略):每种具体策略,实现不同的行为

你可以随时通过 Context 设置新的策略来改变行为,就像切换武器一样

示例

csharp
interface IAttackStrategy 
{
    void Attack();
}

class MeleeAttack : IAttackStrategy 
{
    public void Attack() => Console.WriteLine("近身砍一刀!");
}

class RangedAttack : IAttackStrategy 
{
    public void Attack() => Console.WriteLine("远程射箭!");
}

class MagicAttack : IAttackStrategy 
{
    public void Attack() => Console.WriteLine("释放火球术!");
}

class Hero 
{
    public IAttackStrategy Strategy { get; set; }

    public void PerformAttack() 
    {
        Strategy.Attack();
    }
}

// 使用:
var hero = new Hero();
hero.Strategy = new MeleeAttack();
hero.PerformAttack(); // 砍一刀

hero.Strategy = new MagicAttack();
hero.PerformAttack(); // 扔火球

GDScript

gdscript
class AttackStrategy:
    func attack():
        pass

class MeleeAttack extends AttackStrategy:
    func attack():
        print("近战攻击!")

class RangedAttack extends AttackStrategy:
    func attack():
        print("射箭射爆!")

class Hero:
    var strategy: AttackStrategy

    func perform_attack():
        strategy.attack()
        
func _ready():
    var hero = Hero.new()
    hero.strategy = MeleeAttack.new()
    hero.perform_attack() # 近战攻击!

    hero.strategy = RangedAttack.new()
    hero.perform_attack() # 射箭射爆!