策略模式之策略模式

1.模式简介

        定义一组算法,将每个算法封装起来,并且使它们之间可以相互转化。

2.主要思想

        定义一个通用的问题,使用不同的算法来实现,然后将这些算法都封装在一个统一接口。

策略模式使用的就是OOP的继承和多态。   

3.模式优点

  • 符合开放封闭原则
  • 代替if else,降低代码的耦合度

4.模式缺点

  • 客户端必须知道所有的策略类,并决定使用哪个策略类
  • 产生很多策略类

5.模式使用

       模式使用一般结合工厂方法模式一起使用

  • 定义公共方法(月卡时段计算)

/**
 * 月卡时段计算
 */
public interface CardPeriodPeriodStrategy {

	/**
	 * 计算月卡有效期的共同算法
	 *
	 * @param cardDurationDTO cardDurationDTO
	 * @return CardDurationVO
	 */
	CardDurationVO getCardPeriod(CardDurationDTO cardDurationDTO, Card card, CardCategory cardCategory);
}

  • 具体实现(自然月计算)
@Component
@AllArgsConstructor
public class CardPeriodNaturalMonthStrategy extends AbstractCardPeriodService implements CardPeriodPeriodStrategy {


	@Override
	public CardDurationVO getCardPeriod(CardDurationDTO cardDurationDTO, Card card, CardCategory cardCategory) {


		Date startDate = getStartDate(cardDurationDTO.getStartDate(), card);
		Date endDate = cardDurationDTO.getEndDate();
		LecentAssert.notNull(endDate, "请选择结束时间!");
		LecentAssert.isTrue(startDate.before(endDate), "结束时间必须大于开始时间");

		//缴费月数
		int monthNum = getRenewalMonths(startDate, endDate);

		BigDecimal unitPrice = getUnitPrice(monthNum, cardCategory);

		return buildCardDuration(startDate, endDate, monthNum, unitPrice);
	}
}

天对天计算

@Component
@AllArgsConstructor
public class CardPeriodDay2DayStrategy extends AbstractCardPeriodService implements CardPeriodPeriodStrategy {


	@Override
	public CardDurationVO getCardPeriod(CardDurationDTO cardDurationDTO, Card card, CardCategory cardCategory) {


		Date startDate = getStartDate(cardDurationDTO.getStartDate(), card);

		Integer monthNum = cardDurationDTO.getMonthNum();
		LecentAssert.notNull(monthNum, "请选择缴费月数!");

		Date endDate = calculateEndDate(startDate, monthNum);

		BigDecimal unitPrice = getUnitPrice(monthNum, cardCategory);

		return buildCardDuration(startDate, endDate, monthNum, unitPrice);

	}
  • 定义工厂方法
@AllArgsConstructor
@Component
public class CardPeriodHandler {

	private static Map<Integer, CardPeriodPeriodStrategy> map = new ConcurrentHashMap<>();


	private final CardPeriodNaturalMonthStrategy cardNaturalMonthStrategy;
	private final CardPeriodDay2DayStrategy cardDay2DayStrategy;
	private final CardPeriodDay2DayEarlyEndStrategy cardDay2DayEarlyEndStrategy;
	private final CardPeriodManyDaysStrategy cardManyDaysStrategy;

	@PostConstruct
	public void init() {
		map.put(CardDurationTypeEnum.DAY_2_DAY.getRenewWay(), cardDay2DayStrategy);
		map.put(CardDurationTypeEnum.NATURAL_MONTH.getRenewWay(), cardNaturalMonthStrategy);
		map.put(CardDurationTypeEnum.DAY_2_DAY_EARLY_END.getRenewWay(), cardDay2DayEarlyEndStrategy);
		map.put(CardDurationTypeEnum.MANY_DAYS.getRenewWay(), cardManyDaysStrategy);
	}

	public CardPeriodPeriodStrategy getHandler(Integer renewType) {
		return map.get(renewType);
	}
}
  • 业务类调用​​​​​​​
    @Override
    	public CardDurationVO getTimeDuration(CardDurationDTO cardDurationDTO) {
    
    
    		CardPeriodPeriodStrategy handler = cardPeriodHandler.getHandler(cardDurationDTO.getRenewWay());
    		LecentAssert.notNull(handler, "无效的续费类型");
    
    		return handler.getCardPeriod(cardDurationDTO, card, cardCategory);
    	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值