06_Strategy Pattern 策略模式 ——情况有变,全体切换执行Plan B

GoF 定义: 定义一个系列的算法,然后封装每个算法,使得他们之间可以互换。策略模式使得算法在客户端之间可以独立地变化。(Define a family of algorithms, encapsulate each one, and make them interchangeable. The strategy pattern lets the algorithm vary independently from client to client.)

进一步解释:策略模式是把算法封装成相同的接口,然后在运行时按需动态调用。一旦有了统一接口,客户端就可用用同一份代码处理不同的情况,要做的只是在此之前设置不同的算法子类。

例如,有一个段子讲的是:“一个标准的程序员在睡觉时候都会准备两个杯子,一个是空的,一个装满了水。装满水的杯子为的是醒来之后口渴,空白杯子是为了万一醒来之后不渴。”这位哥们一看就是学过设计模式的科班出身,把策略模式用到了生活中。

我们用代码表述这个情景:

import java.util.Random;

/**
 * strategy pattern
 */
public class Main {
    public static void main(String[] args) {
        String[] conditionArray = {"Thirsty", "NotThirsty"};
        // 实例化两个算法类
        IPickCup whenThirsty = new PickCupWhenThirsty();
        IPickCup whenNotThirsty = new PickCupWhenNotThirsty();
        WakeUp wakeUp = new WakeUp();
        for (int i = 0; i < 10; i++) {
            // 循环10次,随机生成口渴和不渴的情形
            String condition = conditionArray[new Random().nextInt(2)];
            System.out.println("\nTime "+ i + " I'm "+condition);
            // 根据情况传入不同的算法
            if (condition.equals("Thirsty")){
                wakeUp.setPickCup(whenThirsty);
            } else {
                wakeUp.setPickCup(whenNotThirsty);
            }
            wakeUp.doRegular();
        }
    }
}

// 喝水动作的接口函数
abstract class IPickCup {
    abstract void pickUpCup();
}

// 感觉口渴时
class PickCupWhenThirsty extends IPickCup {
    @Override
    void pickUpCup() {
        System.out.println("Pick up the cup");
        System.out.println("Drink...");
        System.out.println("Put down the cup");
        System.out.println("And continue go to sleep");
    }
}

// 万一不渴
class PickCupWhenNotThirsty extends IPickCup {
    @Override
    void pickUpCup() {
        System.out.println("pick up the cup");
        System.out.println("Put down the cup");
        System.out.println("And continue go to sleep");
    }
}

class WakeUp {
    IPickCup pickCup = null;

    // 在这里动态加载不同的算法(即渴不渴的情况)
    void setPickCup(IPickCup pickCup) {
        this.pickCup = pickCup;
    }

    // 策略模式可以使用同一份代码处理不同的情况
    void doRegular() {
        System.out.println("I am waking up");
        pickCup.pickUpCup();
    }
}

类图:

输出:

策略模式的关键在于实现具有统一接口的算法类(这里的杯子就是接口,因此就算没有水,杯子还是要有的),然后用不同的算法类处理不同的情形(口渴和不口渴)。在调用过程中,客户端程序根据不同情形动态加载不同的算法(WakeUp 类中的setPickCup()方法)。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值