设计模式(15)—— 行为型 ——策略(Strategy)

介绍

  • 定义:定义算法家族,分别封装起来,让他们之间可以相互调用,此模式让算法的变化不会影响到使用算法的用户
  • 说明:大量的if…else…结构,使用策略模式减少或者消除此结构。
  • 适用场景
    • 系统有很多类,而他们的区别仅仅在于他们的行为不同
    • 一个系统需要动态地在几个算法中选择一个
  • 优点
    • 符合开闭原则
    • 避免使用多重条件转移语句,例如 if…else or switch
    • 提高算法的保密性,安全性
  • 缺点
    • 客户端必须知道所有的策略类,并自行决定使用哪一个策略
    • 产生很多策略类
  • 相关设计模式
    • 策略模式和工厂模式
    • 策略模式和状态模式

代码实现(简单版)

业务场景:最近天气总是变化,搞得小明一下穿毛衣(Sweater),一下穿短袖(Short),一下穿长袖(Long)。据此我们模拟此场景。

天气不停地变化,我们定义一个天气变化类WeatherChanged。根据天气变化的不同,我们采取不同的穿衣策略:穿毛衣(SweaterDressStrategy)穿短袖(ShortDressStrategy)穿长袖(LongDressStrategy)

下面是具体的代码实现。

首先我们定义一个穿衣策略的接口类DressStrategy

/**
 * 穿衣服的接口策略类
 */
public interface DressStrategy {
   void wear();
}

三种穿衣策略的具体接口实现:

/**
 * 穿毛衣策略
 */
public class SweaterDressStrategy implements DressStrategy {
    @Override
    public void wear() {
        System.out.println("穿毛衣");
    }
}

/**
 * 穿长袖策略
 */
public class LongDressStrategy implements DressStrategy {
    @Override
    public void wear() {
        System.out.println("穿长袖");
    }
}

/**
 * 穿短袖策略
 */
public class ShortDressStrategy implements DressStrategy {
    @Override
    public void wear() {
        System.out.println("穿短袖");
    }
}

下面是天气变化类。这里我们的实现思路是:外部感知天气的变化,然后采取不同的策略。对应于下面的代码就是,客户端(上层)根据具体的情况传入具体的DressStrategy穿衣服策略。

/**
 * 天气变化类
 */
public class WeatherChanged {

    /**
     * 成员变量,策略。反应天气变化后 该执行的穿衣策略
     */
    private DressStrategy dressStrategy;

    /**
     * 构造函数
     * @param dressStrategy 传入穿衣策略
     */
    public WeatherChanged(DressStrategy dressStrategy) {
        this.dressStrategy = dressStrategy;
    }

    /**
     * 执行策略的相应动作
     */
    public void onAction(){
        this.dressStrategy.wear();
    }

}

测试类(客户端,上层应用)的测试代码:

public class Test {
    public static void main(String[] args) {

        // 天气太热了,我要穿短袖
        WeatherChanged weatherChanged0 = new WeatherChanged( new ShortDressStrategy() );
        weatherChanged0.onAction();

        // 天气比较凉快,我要穿长袖
        WeatherChanged weatherChanged1 = new WeatherChanged( new LongDressStrategy() );
        weatherChanged1.onAction();

        // 天气太冷了,我要穿毛衣
        WeatherChanged weatherChanged2 = new WeatherChanged( new SweaterDressStrategy() );
        weatherChanged2.onAction();

        //控制台输出结果:
        /*
        穿短袖
        穿长袖
        穿毛衣
         */
    }
}

代码实现(结合工厂模式)

注意到上面的测试类中,每个策略都需要我们一个个通过new操作符来依次获取,比较麻烦。现在我们通过工厂类来获取特定的策略

/**
 * 天气变化,策略生成工厂
 */
public class WeatherChangedStrategyFactory {

    public static final int WEATHER_CHANGED_MODE_COLD = -1;       // 凉爽
    public static final int WEATHER_CHANGED_MODE_HOT = 0;         // 炎热
    public static final int WEATHER_CHANGED_MODE_COLDER = 1;      // 冬天

    private static Map<Integer, DressStrategy> mp = new HashMap<>();

    static {
        mp.put( WEATHER_CHANGED_MODE_COLD, new LongDressStrategy() );
        mp.put( WEATHER_CHANGED_MODE_HOT, new ShortDressStrategy() );
        mp.put( WEATHER_CHANGED_MODE_COLDER, new SweaterDressStrategy() );
    }

    private WeatherChangedStrategyFactory(Integer WEATHER_CHANGED_MODE){
    }

    public static DressStrategy getStrategy(Integer WEATHER_CHANGED_MODE){
        if( mp.containsKey( WEATHER_CHANGED_MODE ) )
            return mp.get( WEATHER_CHANGED_MODE );
        return null;
    }

}

测试类很简单:

public class Test {
    public static void main(String[] args) {
        //Integer mode = WeatherChangedStrategyFactory.WEATHER_CHANGED_MODE_COLD;
        Integer mode = WeatherChangedStrategyFactory.WEATHER_CHANGED_MODE_COLDER;
        //Integer mode = WeatherChangedStrategyFactory.WEATHER_CHANGED_MODE_HOT;

        DressStrategy dressStrategy = WeatherChangedStrategyFactory.getStrategy( mode );
        dressStrategy.wear();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值