第十六章 策略模式

快速导航
一、策略模式介绍
二、代码演示
三、jdk中使用 策略模式的地方
一、 策略模式介绍

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

if…else if …else if…else 模式

适用场景:
系统有很多类,而他们的区别仅仅在于他们的行为不同

一个系统需要动态地在几种算法中选择一种

优点:
开闭原则
避免使用多重条件转移语句
提高算法的保密性和安全性

缺点:
客户端必须知道所有的策略类,并自行决定使用哪一个策略类
产生很多策略类

相关设计模式:
策略模式和工厂模式
策略模式和状态模式

二、代码演示
//策略接口

public interface PromotionStrategy {
    void doPromotion();
}

//返现策略
public class FanXianPromotionStrategy implements PromotionStrategy{
    @Override
    public void doPromotion() {
        System.out.println("返现促销,返回的金额存放到慕课网用户的余额中");
    }
}
//立减策略
public class LiJianPromotionStrategy implements PromotionStrategy {
    @Override
    public void doPromotion() {
        System.out.println("立减促销,课程的价格直接减去配置的价格");
    }
}
//满减策略
public class ManJianPromotionStrategy implements PromotionStrategy{
    @Override
    public void doPromotion() {
        System.out.println("满减促销,满200-20元");
    }
}
//活动类
public class PromotionActivity {
    private PromotionStrategy promotionStrategy;
    public PromotionActivity(PromotionStrategy promotionStrategy) {
        this.promotionStrategy = promotionStrategy;
    }
    public void executePromotionStrategy(){
        promotionStrategy.doPromotion();
    }
}

//测试类
public class Test {
    public static void main(String[] args) {
        PromotionActivity promotionActivity618 = new PromotionActivity(new LiJianPromotionStrategy());
        PromotionActivity promotionActivity1111 = new PromotionActivity(new FanXianPromotionStrategy());

        promotionActivity618.executePromotionStrategy();
        promotionActivity1111.executePromotionStrategy();
    }
}

来看一下类的uml图:
在这里插入图片描述

执行结果: 按结果来看是按选择的策略执行的。
在这里插入图片描述

以上测试方法,需要强依赖PromotionStrategy 的实现类,每改一次都得改子类实现。

下面我们来优化一下代码,改为工厂模式:

//策略模式工厂
public class PromotionStrategyFactory {
    private static final Map<String,PromotionStrategy> PROMOTION_STRATEGY_MAP=new HashMap<String,PromotionStrategy>();
    private interface PromotionKey{
        String LIJIAN="LIJIAN";
        String FANXIAN="FANXIAN";
        String MANJIAN="MANJIAN";
    }
    static {
        PROMOTION_STRATEGY_MAP.put(PromotionKey.LIJIAN,new LiJianPromotionStrategy());
        PROMOTION_STRATEGY_MAP.put(PromotionKey.FANXIAN,new FanXianPromotionStrategy());
        PROMOTION_STRATEGY_MAP.put(PromotionKey.MANJIAN,new ManJianPromotionStrategy());
    }
    private PromotionStrategyFactory() { }
    public static PromotionStrategy getPromotionStrategy(String key){
        PromotionStrategy promotionStrategy = PROMOTION_STRATEGY_MAP.get(key);
        return promotionStrategy==null? new NoPromotionStrategy():promotionStrategy;
    }
}

//添加了无优惠的子实现类
public class NoPromotionStrategy implements PromotionStrategy {
    @Override
    public void doPromotion() {
        System.out.println("无优惠活动");
    }
}
//测试类
public class Test {
    public static void main(String[] args) {
        String strategy="MANJIAN";
        PromotionStrategy promotionStrategy = PromotionStrategyFactory.getPromotionStrategy(strategy);
        PromotionActivity promotionActivity = new PromotionActivity(promotionStrategy);
        promotionActivity.executePromotionStrategy();
    }
}

运行结果仍然是满足我们预期的:
在这里插入图片描述

三、jdk中使用 策略模式的地方

1、java.util.Comparator

java.util.Arrays 中的 sort() 方法是把 Comparator 作为参数,继续向下传,这就是策略模式在jdk中的典型应用。

在这里插入图片描述

2、java.util.TreeMap

在这里插入图片描述

3、org.springframework.core.io.Resource

下图标红的框都是 org.springframework.core.io.Resource 的行为策略实现

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值