策略模式

2023/10/20

# 策略模式(Strategy Pattern)

策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,并将每一个算法封装起来,并且使它们可以相互替换。策略模式让算法独立于使用它的客户而独立变化。这意味着如果你的程序中有一些在不同时间使用不同策略的类,那么使用策略模式可以动态地更改类的操作算法。

让我们通过一个例子来理解策略模式:

假设你正在开发一个导航应用程序,该应用程序需要提供多种方式来计算路线,比如:最快路线、避开高速公路、步行路线等。每种路线计算方式都可以被视为一个策略。

以下是这个例子的伪代码实现:

// 定义策略接口。这里的策略是路线计算
interface RouteStrategy {
    String buildRoute(String pointA, String pointB);
}

// 第一个具体策略类:最快路线
class FastestRoute implements RouteStrategy {
    public String buildRoute(String pointA, String pointB) {
        // ... 具体算法实现
        return "The fastest route from " + pointA + " to " + pointB;
    }
}

// 第二个具体策略类:避开高速
class AvoidHighwaysRoute implements RouteStrategy {
    public String buildRoute(String pointA, String pointB) {
        // ... 具体算法实现
        return "The route avoiding highways from " + pointA + " to " + pointB;
    }
}

// 第三个具体策略类:步行路线
class WalkingRoute implements RouteStrategy {
    public String buildRoute(String pointA, String pointB) {
        // ... 具体算法实现
        return "The walking route from " + pointA + " to " + pointB;
    }
}

// 上下文,使用策略的类
class NavigationApp {
    private RouteStrategy routeStrategy;

    // 在构造函数中或者通过setter方法可以设置初始策略
    public NavigationApp(RouteStrategy routeStrategy) {
        this.routeStrategy = routeStrategy;
    }

    public void setRouteStrategy(RouteStrategy routeStrategy) {
        this.routeStrategy = routeStrategy;
    }

    public String buildRoute(String pointA, String pointB) {
        // 使用策略对象的方法
        return this.routeStrategy.buildRoute(pointA, pointB);
    }
}

// 客户端代码
public class StrategyPatternExample {
    public static void main(String[] args) {
        // 初始策略为最快路线
        NavigationApp navigationApp = new NavigationApp(new FastestRoute());

        // 根据用户需求,可以改变策略
        navigationApp.setRouteStrategy(new AvoidHighwaysRoute());
        System.out.println(navigationApp.buildRoute("PointA", "PointB"));

        // 可以随时改变策略
        navigationApp.setRouteStrategy(new WalkingRoute());
        System.out.println(navigationApp.buildRoute("PointA", "PointB"));
    }
}