设计模式-策略模式

115 阅读2分钟

基本概念

在策略模式(Strategy Pattern)中一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式定义了一系列算法或策略,并将每个算法封装在独立的类中,使得它们可以互相替换。通过使用策略模式,可以在运行时根据需要选择不同的算法,而不需要修改客户端代码。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
如何解决:将这些算法封装成一个一个的类,任意地替换。
关键代码:实现同一个接口

主要组成

  • 环境(Context):维护一个对策略对象的引用,负责将客户端请求委派给具体的策略对象执行。环境类可以通过依赖注入、简单工厂等方式来获取具体策略对象。
  • 抽象策略(Abstract Strategy):定义了策略对象的公共接口或抽象类,规定了具体策略类必须实现的方法。
  • 具体策略(Concrete Strategy):实现了抽象策略定义的接口或抽象类,包含了具体的算法实现。

uml图

be606cc56adeb7a62ba50c94a6455cd.png

代码

  • GameContext【环境类】
package com.wu.strategy;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName GameContext
 * @Description: 环境类,对外提供方法获取策略
 * @Author: wu
 * @CreateDate: 2024/3/22 10:37
 */
@Component
public class GameContext {

    @Autowired
    Map<String,GameStrategy> gameStrategyMap = new HashMap<>();


    GameStrategy getGameStrategy(String name){
        return gameStrategyMap.get(name);
    }
}
  • GameStrategy【抽象策略】
package com.wu.strategy;

/**
 * @ClassName GameStrategy
 * @Description: 游戏策略的抽象接口
 * @Author: wu
 * @CreateDate: 2024/3/22 10:38
 */
public interface GameStrategy {

    /**
     * 打游戏
     * @return
     */
    String playGame();

    /**
     * 游戏名
     * @return
     */
    String game();
}
  • CFGame【具体策略】
package com.wu.strategy;

import org.springframework.stereotype.Component;

/**
 * @ClassName CFGame
 * @Description: DNF游戏
 * @Author: wu
 * @CreateDate: 2024/3/22 10:40
 */
@Component("DNF")
public class DNFGame implements GameStrategy{
    /**
     * 打游戏
     *
     * @return
     */
    @Override
    public String playGame() {
        return "开始玩DNF";
    }

    /**
     * 游戏名
     *
     * @return
     */
    @Override
    public String game() {
        return "DNF";
    }
}
  • CFGame【具体策略】
package com.wu.strategy;

import org.springframework.stereotype.Component;

/**
 * @ClassName CFGame
 * @Description: CF游戏
 * @Author: wu
 * @CreateDate: 2024/3/22 10:40
 */
@Component("CF")
public class CFGame implements GameStrategy{
    /**
     * 打游戏
     *
     * @return
     */
    @Override
    public String playGame() {
        return "开始玩CF";
    }

    /**
     * 游戏名
     *
     * @return
     */
    @Override
    public String game() {
        return "CF";
    }
}
  • GameContextTest【测试类】
package com.wu.strategy;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class GameContextTest {
    @Autowired
    GameContext gameContext;
    @Test
    void getGameStrategy() {
        GameStrategy dnf = gameContext.getGameStrategy("DNF");
        System.out.println(dnf.playGame());
        GameStrategy cf = gameContext.getGameStrategy("CF");
        System.out.println(cf.playGame());
    }
}