Java设计模式(一) 策略模式

策略模式简介:

策略模式对应于解决某一个问题的一个算法族(多个算法),允许用户从该算法族中任选一种算法解决某一问题;同时,可以方便的更换算法或用户自定义新的算法;并且由用户决定调用最终使用哪个算法。

应用场景如下:
模拟商场购物场景,不同会员等级的客户会有不同的打折策略。具体代码如下:

public class Strategy {

    /**
     * 根据不同的用户对商品打折
     * @param price
     * @return
     */
    public BigDecimal discounted(VipLevel vipLevel,BigDecimal price){
        switch (vipLevel){
            case PT:
                return price.multiply(new BigDecimal(0.6));
            case GOLD:
                return price.multiply(new BigDecimal(0.7));
            case SILVER:
                return price.multiply(new BigDecimal(0.8));
            case COPPER:
                return price.multiply(new BigDecimal(0.9));
            default:
                return null;
        }
    }
}

枚举类,定义会员等级

/**
 * 会员等级
 */
public enum VipLevel {
    PT("pt"),
    GOLD("gold"),
    SILVER("silver"),
    COPPER("copper");

     String level;

    VipLevel(String level) {
        this.level = level;
    }
}

虽然有点样子了,但这种实现方式肯定不是我们最终想要的,原因有以下三点:
1.每次新增算法都要改这个类,违反开闭原则;
2.策略多了非常不好维护;
3.业务和策略耦合在一起

所以我们来将其改造成真正的策略模式:
我们先定义一个策略接口:
该方法就是说,传进来一个原价格,我根据具体的实现返回给一个打折后的价格。

public interface Strategy {
    BigDecimal discounted(BigDecimal price);
}
image.png

编写几个实现:
黄金会员

public class GoldStrategy implements Strategy {
    @Override
    public BigDecimal discounted(BigDecimal price) {
        return price.multiply(new BigDecimal(0.7));
    }
}

青铜会员


public class CopperStrategy implements Strategy {
    @Override
    public BigDecimal discounted(BigDecimal price) {
        return price.multiply(new BigDecimal(0.9));
    }
}

既然销售策略有了,现在我们再定义一个销售职员接口:
销售人员只关注价格,不关注算法。

/**
 * 销售员接口
 *
 */
public interface Saler {
    BigDecimal coculate(BigDecimal price);
}

定义一个抽象类,继承这个抽象类的子类都需要带有一个策略,白话就是说这一类的销售人员都需要使用实现了Strategy接口的策略去计算价格。


public abstract class ProductionSaler implements Saler{

    protected Strategy strategy;

    public ProductionSaler(Strategy strategy) {
        this.strategy = strategy;
    }
    
}

具体的销售人员:

public class RealSaler extends ProductionSaler{

    public RealSaler(Strategy strategy) {
        super(strategy);
    }

    @Override
    public BigDecimal coculate(BigDecimal price) {
        return strategy.discounted(price);
    }
}

测试类:

public class Test {
    public static void main(String[] args) {
        Saler saler = new RealSaler(new CopperStrategy());
        System.out.println(saler.coculate(new BigDecimal(60)));
    }
}
image.png

最终我们达到了业务与算法的分离。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。