策略模式

策略模式

使用策略模式,可以使一个类的行为在运行时得到改变。为了使用策略模式,首先我们需要创建一些列的算法,将他们进行封装,并且使他们可以相互替换(具体为所有的策略算法都实现自同一个interface)。使用策略模式可以使得代码中减少很多的 if... else 结构。下面通过一个场景对比 if... else 和策略模式。

出去旅游的时候,我们经常根据天气决定我们的行为。例如:下雨的时候我们则会选择室内,例如博物馆;晴天的时候我们则会选择公园等景色比较好的地方;当遇到极端天气的时候我们一般宅在家里不出门。

针对以上场景,我们很容易写出一下 if... else 的代码:

public void doAction(String weather) {
    if("rainy".equals(weather)) {
        System.out.println("下雨了,我们去博物馆吧");
    }
    if ("sunny".equals(weather)) {
        System.out.println("晴天了,我们去公园吧");
    }
    if ("very-bad".equals(weather)) {
        System.out.println("极端天气,我们宅在家吧");
    }
}

乍一看这样的代码没有问题,确实这样的代码毫无问题,当时随着越来越多的条件,就会有越来越多的 if... else ,使得代码变得冗长。那如何使得精简这样的代码呢?答案就是本文的主人公:策略模式。
策略模式要求我们提前定义好一些列的策略算法:

// 定义接口
public interface IAction {
    void doAction();
}

// 下雨天策略类
public class RainyAction implements IAction {
    @Override
    public void doAction() {
        System.out.println("下雨了,我们去博物馆吧");
    }
}

// 晴天策略类
public class SunnyAction implements IAction {
    @Override
    public void doAction() {
        System.out.println("晴天了,我们去公园吧");
    }
}

// 极端天气策略类
public class VeryBadAction implements IAction {
    @Override
    public void doAction() {
        System.out.println("极端天气,我们宅在家吧");
    }
}

在使用时,我们根据不同的天气,选择不同的策略类即可:

public class Client {
    public static void main(String[] args) {
        Map<String, IAction> map = new HashMap<>();
        map.put("rainy", new RainyAction());
        map.put("sunny", new SunnyAction());
        map.put("very-bad", new VeryBadAction());

        map.get("rainy").doAction();            // 输出:下雨了,我们去博物馆吧
        map.get("sunny").doAction();            // 输出:晴天了,我们去公园吧
        map.get("very-bad").doAction();         // 输出:极端天气,我们宅在家吧
    }
}

通过上面代码发现,我们将之前的每一个 if... else 分支,变成了一个策略类。根据不同的场景,选择对应的策略类,执行对应的策略方法。经过对比我们可以现在策略模式的一些优缺点:
优点:

  1. 代码比 if... else 更加优雅。当if越多时,提现的越明显
  2. 扩展性好。当添加新的策略时,只需新编写一个策略类即可,符合“开闭原则”

缺点:

  1. 策略类会非常多。之前的 if... else 只集中在一个类里,现在需要扩展多个类。
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务