[01][01][06] 策略模式详解

1. 定义

策略模式: 指定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式上算法的变化不会影响到使用算法的用户

可以避免多重分支的if...esleswitch语句

2. 适用场景

Spring中以Strategy结尾的类都是策略模式的体现

3. 代码实现

  • 通过工厂模式 + 单例模式 + 策略模式的方式实现
  • 后面增加策略只需要增加对应的具体策略, 在策略枚举中增加对应的策略名称, 在工厂中增加对应的策略就能完成策略活动的增加, 不需要修改过多的代码, 对于用户而言是无感知的

3.1 策略抽象类

package com.zhunongyun.toalibaba.designpatterns.strategy.promotion;

public interface PromotionStrategy {
    /**
     * 优惠活动
     */
    void doPromotion();
}

3.2 具体策略

package com.zhunongyun.toalibaba.designpatterns.strategy.promotion;

/**
 * 返现活动
 */
public class CashBackStrategy implements PromotionStrategy {
    @Override
    public void doPromotion() {
        System.out.println("正在执行返现活动");
    }
}
package com.zhunongyun.toalibaba.designpatterns.strategy.promotion;

/**
 * 优惠券活动
 */
public class CouponStrategy implements PromotionStrategy {
    @Override
    public void doPromotion() {
        System.out.println("领取优惠券,正在执行优惠券活动");
    }
}
package com.zhunongyun.toalibaba.designpatterns.strategy.promotion;

/**
 * 无促销活动
 */
public class EmptyStrategy implements PromotionStrategy {

    @Override
    public void doPromotion() {
        System.out.println("无促销活动");
    }
}

3.3 策略枚举

package com.zhunongyun.toalibaba.designpatterns.strategy.promotion;

public enum PromotionEnum {
    /**
     * 返现
     */
    CASHBACK,
    /**
     * 优惠券
     */
    COUPON,
    /**
     * 无活动
     */
    EMPTY
}

3.4 策略工厂

package com.zhunongyun.toalibaba.designpatterns.strategy.promotion;

import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;

/**
 * 工厂模式 + 单例模式
 */
public class PromotionStrategyFactory {

    private static Map<Enum, PromotionStrategy> PROMOTION_STRATEGY_MAP = new HashMap<>();

    static {
        PROMOTION_STRATEGY_MAP.put(PromotionEnum.CASHBACK, new CashBackStrategy());
        PROMOTION_STRATEGY_MAP.put(PromotionEnum.COUPON, new CouponStrategy());
        PROMOTION_STRATEGY_MAP.put(PromotionEnum.EMPTY, new EmptyStrategy());
    }

    private PromotionStrategyFactory() {}

    public static PromotionStrategy getPromotionStrategy (PromotionEnum promotionEnum) {
        return PROMOTION_STRATEGY_MAP.get(promotionEnum);
    }
}

3.5 测试类

package com.zhunongyun.toalibaba.designpatterns.strategy.promotion;

public class PromotionStrategyTest {
    public static void main(String[] args) {
        PromotionStrategy promotionStrategy = PromotionStrategyFactory.getPromotionStrategy(PromotionEnum.CASHBACK);
        promotionStrategy.doPromotion();
    }
}

4. 源码分析

4.1 Arrays中的parallelSort

在Arrays中parallelSort是用来排序的,其中存在一个方法是可以自定义排序策略的,用户可以自己实现Comparator定义自己的排序策略

public class Arrays {
    public static <T> void parallelSort(T[] a, Comparator<? super T> cmp) {
        if (cmp == null)
            cmp = NaturalOrder.INSTANCE;
        int n = a.length, p, g;
        if (n <= MIN_ARRAY_SORT_GRAN ||
            (p = ForkJoinPool.getCommonPoolParallelism()) == 1)
            TimSort.sort(a, 0, n, cmp, null, 0, 0);
        else
            new ArraysParallelSortHelpers.FJObject.Sorter<T>
                (null, a,
                 (T[])Array.newInstance(a.getClass().getComponentType(), n),
                 0, n, 0, ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
                 MIN_ARRAY_SORT_GRAN : g, cmp).invoke();
    }
}

4.2 Spring中Resource

Spring的Resource类的实现类就是策略模式的体现

在这里插入图片描述

5. 优缺点

5.1 优点

  • 策略模式符合开闭原则
  • 避免使用多重条件转移语句,如if…else语句,switch语句
  • 使用策略模式可以提高算法的保密性和安全性

5.2 缺点

  • 客户端必须知道所有的策略,并且自行决定使用哪一个策略
  • 代码中会产生非常多策略类,增加维护难度
发布了29 篇原创文章 · 获赞 10 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/csharpqiuqiu/article/details/100057189