策略模式


定义

定义一组算法,将每个算法封装起来,并且它们之间可以互换

使用场景

  1. 多个类只有在算法或者行为上不同的场景
  2. 算法需要自由切换

实现方式

一般判断条件的代码,可以使用策略模式优化

public double getPrice(String type, double price) {
    if (type.equals("gerneral")) {
        System.out.println("打九折");
        return price * 0.9;
    } else if (type.equals("vip")) {
        System.out.println("打八五折");
        return price * 0.85;
    } else if (type.equals("superVip")) {
        System.out.println("打八折");
        return price * 0.8;
    }
    return price;
}

策略的接口

public interface Strategy {
    public double getPrice(double standardPrice);
}

策略的实现类

public class GeneralCustomerStrategy implements Strategy {
    @Override
    public double getPrice(double standardPrice) {
        System.out.println("打九折");
        return standardPrice*0.9;
    }
}

public class VipCustomerStrategy implements Strategy {
    @Override
    public double getPrice(double standardPrice) {
        System.out.println("打八五折");
        return standardPrice*0.85;
    }
}

public class SuperVipCustomerStrategy implements Strategy {
    @Override
    public double getPrice(double standardPrice) {
        System.out.println("打八折");
        return standardPrice*0.8;
    }
}

对外的入口

public class Context {

    private Strategy strategy;  

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }
    
    public double getPrice(double s){
         double result = strategy.getPrice(s);
         System.out.println("您需要付款:" + result);
         return result;
    }
}

测试类

public static void main(String[] args) {
    Strategy s1 = new VipCustomerStrategy();
    Context ctx = new Context(s1);
    ctx.pringPrice(998);
}

扩展与思考

  1. 使用Spring情况下,可以不用自己创建StrategyFactory,可以用ApplicationContext来获取Strategy的bean
  2. 多种判断条件的代码,可以考虑使用策略模式重构。
  3. 上述例子中在测试类暴露了具体的策略Strategy,这不太合适,一般会反射或者工厂模式来获取策略类。
public class StrategyFactory {

    public static Map<String, Strategy> map = new HashMap<>();
    
    static {
        map.put("gerneral", new GeneralCustomerStrategy());
        map.put("vip", new VipCustomerStrategy());
        map.put("superVip", new SuperVipCustomerStrategy());
    }
    
    public static Strategy getStrategy(String type) {
        return map.get(type);
    }
}
public class Context {

    private Strategy strategy;  

    public void setStrategyType(String type) {
        this.strategy = StrategyFactory.getStrategy(type);
    }
    
    public double getPrice(double s){
         double result = strategy.getPrice(s);
         System.out.println("您需要付款:" + result);
         return result;
    }
}

则最初的if-else的代码可以改为

public double getPrice(String type, double price) {
    Context ctx = new Context();
    ctx.setStrategyType(type);
    return ctx.getPrice(price);
}
优质内容筛选与推荐>>
1、U-Boot编译过程完全分析
2、JQuery学习
3、英特尔是个可以讲理的地儿
4、linux cmd using
5、input文字变色


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号