策略模式应用

127 阅读1分钟

前言

现在有这么一个需求,给每个用户发放优惠券,优惠券的种类包含实物、优惠券、现金等,这里可以使用到策略模式

案例

1. 定义一个工厂类,获取具体的策略

@Component
public class ActivityPrizeFactory {

    /**
     * spring容器
     */
    @Autowired
    private ApplicationContext context;


    public ActivityPrize create(Integer prizeType,Object parameter){
        ActivityPrize activityPrize = null;

        if(PullNewPrizeTypeEnum.MATERIAL.getType() == prizeType){
            activityPrize = context.getBean(MaterialActivityPrize.class);
        }else if(PullNewPrizeTypeEnum.COUPON.getType() == prizeType){
            activityPrize = context.getBean(CouponActivityPrize.class);
        }else if(PullNewPrizeTypeEnum.CASH.getType() == prizeType){
            activityPrize = context.getBean(CashActivityPrize.class);
        }

        activityPrize.setParameter(parameter);
        return activityPrize;
    }
}

2. 定义抽象类,抽取公共方法

public abstract class AbstractActivityPrize {

    /**
     * 保存用户领奖记录信息
     */
    protected void saveUserReceivePrize(ActivityPrizeDTO activityPrize){
        // ...
        pullNewReceivePrizeService.save(userPullNewReceivePrize);
    }

    /**
     * 构建用户领奖记录信息
     */
    protected UserPullNewReceivePrize buildUserPullNewReceivePrize(ActivityPrizeDTO activityPrize){
        // ...
        return UserPullNewReceivePrize;
    }

    /**
     * 创建领取奖品的地址信息
     */
    protected void createAddress(ActivityPrizeDTO activityPrize){
        // ...
        userPullNewAddressInfoService.save(pullNewAddressInfo);
    }

}

3. 定义接口,具体实现类实现不同的策略

public interface ActivityPrize {

    /**
     * 领取奖品
     */
    void receivePrize() throws Exception;

    /**
     * 设置这个组件需要的参数
     */
    void setParameter(Object parameter);
}

4. 具体的策略类

/**
 * 实物奖励
 */
@Component
public class MaterialActivityPrize extends AbstractActivityPrize implements ActivityPrize{

    private ActivityPrizeDTO activityPrize;

    @Override
    public void receivePrize() throws Exception {
        createAddress(activityPrize);

        saveUserReceivePrize(activityPrize);
    }

    @Override
    public void setParameter(Object parameter) {
        activityPrize = (ActivityPrizeDTO) parameter;
    }
}
/**
 * 优惠券奖励
 */
@Component
@Slf4j
public class CouponActivityPrize extends AbstractActivityPrize implements ActivityPrize{

    private ActivityPrizeDTO activityPrize;

    @Autowired
    private UserCouponRepository userCouponRepository;

    @Override
    public void receivePrize() throws Exception {
        // ...
        saveUserReceivePrize(activityPrize);
    }

    @Override
    public void setParameter(Object parameter) {
        activityPrize = (ActivityPrizeDTO) parameter;
    }
}

5. 领奖方法

@Override
public PullNewReceivePrizeRespVO receivePrize(PullNewReceivePrizeReqVO pullNewReceivePrizeReqVO,Integer userId)throws Exception {

    // ...
    ActivityPrizeDTO activityPrizeDTO = new ActivityPrizeDTO();
    activityPrizeDTO.setUserId(userId);
    activityPrizeDTO.setPullNewReceivePrizeReq(pullNewReceivePrizeReqVO);
    activityPrizeDTO.setPullNewActivity(pullNewActivity);
    activityPrizeDTO.setPullNewActivityPrize(pullNewActivityPrize);
    activityPrizeDTO.setUserRespVO(userRespVO);
    activityPrizeDTO.setFitEndPoint(CouponFitEndPointEnum.H5.getCode());

    // 获取不同的策略
    ActivityPrize activityPrize = activityPrizeFactory.create(pullNewActivityPrize.getPrizeType(), activityPrizeDTO);
    //领取奖品
    activityPrize.receivePrize();
}

6. 类关系图

image.png

后记

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