LieBrother原文:
行为型模式:策略模式
十一大行为型模式之五:策略模式。
简介姓名 :策略模式
英文名 :Strategy Pattern
价值观 :集计谋于一身
个人介绍 :
Define a family of algorithms,encapsulate each one,and make them interchangeable.
定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。
(来自《设计模式之禅》)
先看一张拍得不好看的图片
每天上完班回到家第一件事情是干啥?有人一进门就躺在沙发上闭目养神、有人一进门躺在沙发上玩手机、有人一进门就陪自己的小宠物玩等等。而我进门第一件事就是洗澡,洗完澡很容易就把一整天的疲惫感给消除掉,然后就可以开始美好的下班时光。现实没那么美好,洗完澡后还要洗衣服,大学手洗了 4 年的衣服,一出来工作,宿舍第一必需品就是洗衣机。细看洗衣机,有很多种洗衣类型,比如:标准、大物、快洗、轻柔。洗衣类型的区别在于洗衣服的过程不一样,洗衣过程包括有浸泡、洗涤、漂洗、脱水,还有洗衣服的时间也不一样。细想可以发现这 4 种洗衣类型其实是洗衣服的 4 种不同的策略,也即是 4 种不同的算法。根据这个思路,我们可以用代码实现它,定义一个接口 WashingStrategy 定义洗衣服类型,而这些类型都有各自的洗衣过程,比如标准洗衣类型就包括浸泡、洗涤、漂洗、脱水,而快洗则只包括洗涤、漂洗、脱水。而我们洗衣服则需要选择某个洗衣类型后,洗衣机就开始工作了。过程如下代码所示。
public class StrategyTest { public static void main(String[] args) { WashingStrategy washingStrategy = new StandardWashingStrategy(); WashingMachine washingMachine = new WashingMachine(washingStrategy); washingMachine.washingClothes(); } } /** * 洗衣类型 */ interface WashingStrategy { void washing(); } /** * 洗衣机 */ class WashingMachine { private WashingStrategy washingStrategy; public WashingMachine(WashingStrategy washingStrategy) { this.washingStrategy = washingStrategy; } public void washingClothes() { this.washingStrategy.washing(); } } /** * 标准 */ class StandardWashingStrategy implements WashingStrategy{ @Override public void washing() { System.out.println("标准流程:"); System.out.println("[浸泡] 10 分钟"); System.out.println("[洗涤] 2 次,每次 15 分钟"); System.out.println("[漂洗] 1 次,每次 10 分钟"); System.out.println("[脱水] 5 分钟"); System.out.println("总共耗时:55 分钟"); } } /** * 快洗 */ class QuickWashingStrategy implements WashingStrategy { @Override public void washing() { System.out.println("快洗流程:"); System.out.println("[洗涤] 1 次,每次 10 分钟"); System.out.println("[漂洗] 1 次,每次 10 分钟"); System.out.println("[脱水] 5 分钟"); System.out.println("总共耗时:25 分钟"); } } /** * 大物 */ class BigClothesWashingStrategy implements WashingStrategy { @Override public void washing() { System.out.println("大物流程:"); System.out.println("[浸泡] 30 分钟"); System.out.println("[洗涤] 3 次,每次 15 分钟"); System.out.println("[漂洗] 2 次,每次 10 分钟"); System.out.println("[脱水] 5 分钟"); System.out.println("总共耗时:100 分钟"); } } /** * 轻柔 */ class SoftWashingStrategy implements WashingStrategy { @Override public void washing() { System.out.println("轻柔流程:"); System.out.println("[浸泡] 10 分钟"); System.out.println("[漂洗] 2 次,每次 15 分钟"); System.out.println("[脱水] 5 分钟"); System.out.println("总共耗时:45 分钟"); } } 标准流程: [浸泡] 10 分钟 [洗涤] 2 次,每次 15 分钟 [漂洗] 1 次,每次 10 分钟 [脱水] 5 分钟 总共耗时:55 分钟是不是感觉策略模式很简单呢?上面代码就是完整的策略模式示例,是不是感觉有些问题,这 4 种洗衣类型对象完全暴露给了用户,这也是策略模式的缺点。往往策略模式不会单独使用,会和其他设计模式一起使用,比如和简单工厂模式一起使用就可以解决这个对外暴露对象的问题,看下面代码。
/** * 洗衣类型选择 */ class WashingFactory { public static WashingStrategy getWashingStrategy(String type) { if ("Quick".equals(type)) { return new QuickWashingStrategy(); } if ("BigClothes".equals(type)) { return new BigClothesWashingStrategy(); } if ("Soft".equals(type)) { return new SoftWashingStrategy(); } return new StandardWashingStrategy(); } } public class StrategyTest { public static void main(String[] args) { WashingStrategy washingStrategy2 = WashingFactory.getWashingStrategy("Soft"); WashingMachine washingMachine2 = new WashingMachine(washingStrategy2); washingMachine2.washingClothes(); } } 打印结果: 轻柔流程: [浸泡] 10 分钟 [漂洗] 2 次,每次 15 分钟 [脱水] 5 分钟 总共耗时:45 分钟代码中使用 WashingFactory 来封装 4 种策略,使得策略没有对外暴露,我们也了解到设计模式之间具有互补的关系,有些时候并不是单独存在的。
代码:
Strategy Pattern