设计模式——策略模式

策略模式:Strategy,是指,定义一组算法,并把其封装到一个对象中。然后在运行时,可以灵活的使用其中的一个算法。以下记录我对策略模式的理解(部分解释借鉴自廖雪峰老师)

策略模式是为了允许调用方选择一个算法,从而通过不同策略实现不同的计算结果。体现了模块化的思想,不必为了一点小改动而造成程序整体的修改,方便使用者选择不同方案。通过扩展策略,不必修改主逻辑,即可获得新策略的结果。
一个完整的策略模式要定义策略以及使用策略的上下文。我们以网购图书为例,假设网站针对普通顾客、会员有不同的折扣,同时活动期间还有一个满100减20的活动,这些就可以作为策略实现。
先定义打折策略接口:

public interface DiscountStrategy {
    // 计算折扣额度:
    BigDecimal getDiscount(BigDecimal total);
}

策略示意图如下,共有三种打折策略
┌───────────────┐ ┌─────────────────┐
│DiscountContext│─ ─ ─>│DiscountStrategy │
└───────────────┘ └─────────────────┘

│ ┌─────────────────────┐
├─│CommonUserStrategy │
│ └─────────────────────┘
│ ┌─────────────────────┐
├─VIPStrategy│
│ └─────────────────────┘
│ ┌─────────────────────┐
└─│SpecialStrategy │
└─────────────────────┘
要应用策略,需要建立上下文部分

public class DiscountContext {
    // 持有某个策略:
    private DiscountStrategy strategy = new UserDiscountStrategy();

    // 允许客户端设置新策略:
    public void setStrategy(DiscountStrategy strategy) {
        this.strategy = strategy;
    }

    public BigDecimal calculatePrice(BigDecimal total) {
        return total.subtract(this.strategy.getDiscount(total)).setScale(2);
    }
}

接下来,就是三种可供选择的策略。
1.普通顾客和会员的策略:

public class UserDiscountStrategy implements DiscountStrategy {
    public BigDecimal getDiscount(BigDecimal total) {
        // 普通会员打九折:
        return total.multiply(new BigDecimal("0.1")).setScale(2, RoundingMode.DOWN);
    }
}

活动期间促销策略如下

public class OverDiscountStrategy implements DiscountStrategy {
    public BigDecimal getDiscount(BigDecimal total) {
        // 满100减20优惠:
        return total.compareTo(BigDecimal.valueOf(100)) >= 0 ? BigDecimal.valueOf(20) : BigDecimal.ZERO;
    }
}

调用方必须首先创建一个DiscountContext,并指定一个策略(或者使用默认策略),即可获得折扣后的价格:

DiscountContext discount = new DiscountContext();

// 默认策略(普通用户)折扣:
BigDecimal count1 = discount.calculatePrice(BigDecimal.valueOf(120));
System.out.println(count1);

// 活动折扣:
discount.setStrategy(new OverDiscountStrategy());
BigDecimal  count2 = discount.calculatePrice(BigDecimal.valueOf(120));
System.out.println(count2);

// 会员折扣:
discount.setStrategy(new PrimeDiscountStrategy());
BigDecimal  count3 =discount.calculatePrice(BigDecimal.valueOf(120));
System.out.println(count3);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值