策略模式
策略模式
策略模式是一种行为型设计模式,它允许在运行时切换算法或策略。该模式定义一系列算法,将它们分别封装,并使它们可以相互替换。
类图
策略模式的类图由三个部分组成:
- Context:上下文,它持有一个指向具体策略的引用。它将客户端的请求传递给策略对象,并负责控制现有策略和切换策略。
- Strategy:策略,该接口通常由抽象类或接口实现,定义了所有支持的算法的公共接口。它被上下文用于调用具体算法的方法。
- Concrete Strategy:具体策略,它实现了策略接口,提供了特定算法的具体实现。
优点
- 策略模式提供了灵活性,允许在运行时动态更改算法或策略。这样可以在不修改现有代码的情况下修改应用程序的行为。
- 策略模式遵循开闭原则,使应用程序更加可扩展。
- 策略模式提供了松耦合,它将算法与上下文完全分离,并使可复用度更高。
缺点
- 策略模式可能导致增加类的数量,因为每个具体策略都需要一个类来实现它。
- 在使用过程中,客户端必须知道所有可用的策略,才能选择一个特定策略。这可能会使客户端代码变得复杂。
使用场景
- 当客户端需要在执行某些操作时动态更改行为时,策略模式就可以派上用场。
- 当一个系统需要多个算法之一来执行操作,并且需要动态切换它们时,可以使用策略模式。
- 当需要隔离实现,使它们不会影响彼此时,策略模式非常有效。
举例
假设你正在开发一款游戏,该游戏包括一些怪物。它们都有一些相同的功能,例如攻击、防御、移动等。但是每种怪物的攻击、防御、移动方式都不同。你可以使用策略模式来实现这种情况。
首先,我们定义一个抽象类或接口。
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!
以上就是一个简单的策略模式实现的例子。