策略模式


策略模式

策略模式是一种行为型设计模式,它允许在运行时切换算法或策略。该模式定义一系列算法,将它们分别封装,并使它们可以相互替换。

类图

策略模式的类图由三个部分组成:

  1. Context:上下文,它持有一个指向具体策略的引用。它将客户端的请求传递给策略对象,并负责控制现有策略和切换策略。
  2. Strategy:策略,该接口通常由抽象类或接口实现,定义了所有支持的算法的公共接口。它被上下文用于调用具体算法的方法。
  3. Concrete Strategy:具体策略,它实现了策略接口,提供了特定算法的具体实现。

strategy_pattern_diagram.png

优点

  • 策略模式提供了灵活性,允许在运行时动态更改算法或策略。这样可以在不修改现有代码的情况下修改应用程序的行为。
  • 策略模式遵循开闭原则,使应用程序更加可扩展。
  • 策略模式提供了松耦合,它将算法与上下文完全分离,并使可复用度更高。

缺点

  • 策略模式可能导致增加类的数量,因为每个具体策略都需要一个类来实现它。
  • 在使用过程中,客户端必须知道所有可用的策略,才能选择一个特定策略。这可能会使客户端代码变得复杂。

使用场景

  • 当客户端需要在执行某些操作时动态更改行为时,策略模式就可以派上用场。
  • 当一个系统需要多个算法之一来执行操作,并且需要动态切换它们时,可以使用策略模式。
  • 当需要隔离实现,使它们不会影响彼此时,策略模式非常有效。

举例

假设你正在开发一款游戏,该游戏包括一些怪物。它们都有一些相同的功能,例如攻击、防御、移动等。但是每种怪物的攻击、防御、移动方式都不同。你可以使用策略模式来实现这种情况。

首先,我们定义一个抽象类或接口。

public interface Monster {
    void attack();
    void defense();
    void move();
}

接着实现两个具体怪物类吸血鬼和妖精。

public class Vampire implements Monster {
    public void attack() {
        System.out.println("Vampire attack!");
    }
    public void defense() {
        System.out.println("Vampire defend!");
    }
    public void move() {
        System.out.println("Vampire move!");
    }
}

public class Fairy implements Monster {
    public void attack() {
        System.out.println("Fairy attack!");
    }
    public void defense() {
        System.out.println("Fairy defend!");
    }
    public void move() {
        System.out.println("Fairy move!");
    }
}

最后,我们定义一个上下文类,它实现了怪物接口。

public class MonsterContext implements Monster {
    Monster monster;

    public MonsterContext(Monster monster) {
        this.monster = monster;
    }

    public void attack() {
        monster.attack();
    }

    public void defense() {
        monster.defense();
    }

    public void move() {
        monster.move();
    }

    public void setMonster(Monster monster) {
        this.monster = monster;
    }
}

现在,我们可以动态地更改怪物的行为。

public static void main(String[] args) {
    MonsterContext context = new MonsterContext(new Vampire());
    context.attack();
    context.defense();
    context.move();

    context.setMonster(new Fairy());
    context.attack();
    context.defense();
    context.move();
}

以上代码输出:

Vampire attack!
Vampire defend!
Vampire move!

Fairy attack!
Fairy defend!
Fairy move!

以上就是一个简单的策略模式实现的例子。