工厂+策略+模板模式实战

一、前言

最近项目中连续遇到两次业务都需要用到工厂+策略模式来实现。具体业务如下,可以参考参考和自己的业务是不是相似。

1.系统预警功能

这个功能刚开始就包含三十多个指标,后续可能还会增加。为了以后增加指标的时候代码的扩展性强,而不是在一个方法里面if-else,就使用到这种工厂+策略的方式来实现。

2.三重福利功能

这个功能就是判断当前用户是否完成了具体任务,然后领取优惠券。虽然当时接到任务的时候需求就只有三个福利类型,但是为了预防以后增加福利的时候,能快速实现,也就采用了工厂+策略的方式来实现。

二、实现思路

下面通过三重福利来讲一讲具体的思路。

1.业务逻辑

首先需要明白这个功能的实现步骤。三重福利的具体实现思路如下:
在这里插入图片描述
我们会发现其实无论你福利类型怎么变化,有多少个,核心的逻辑就是这几点,这样的话,我们就可以使用模板的方式来实现。

2.工厂搭建

工厂主要是通过福利类型来生产具体的Strategy Handler,然后具体的Strategy Handler根据自己的逻辑去处理具体的业务。
(1)工厂接口:

/**
 * @description: 福利工厂
 * @author: Felix.Du
 * @date: 2021/10/13 4:15 下午
 */
public interface BenefitsFactory {

    /**
     * 根据福利类型创建福利handler
     *
     * @param benefitsType
     * @return 福利handler
     */
    BenefitsHandler createBenefitsHandler(BenefitsTypeEnum benefitsType);
}

(2)工厂实现类:

/**
 * @description:
 * @author: Felix.Du
 * @date: 2021/10/13 4:28 下午
 */
@Component
@Slf4j
public class BenefitsFactoryImpl implements BenefitsFactory, ApplicationContextAware {

    private final Map<Integer, Object> typeToHandlerMap = new HashMap<>();

    private ApplicationContext applicationContext;

    @Override
    public BenefitsHandler createBenefitsHandler(BenefitsTypeEnum benefitsType) {
        try {
            return getHandler(benefitsType);
        } catch (Exception e) {
            log.error("福利类型为{}的handler获取失败,请检查", benefitsType, e);
            throw new RuntimeException();
        }
    }

    @Override
    public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    private BenefitsHandler getHandler(BenefitsTypeEnum benefitsType) {

        BenefitsTypeEnum[] handlers = BenefitsTypeEnum.values();
        if (CollUtil.isEmpty(typeToHandlerMap)
                || !Integer.valueOf(typeToHandlerMap.size()).equals(handlers.length)) {

            initTypeToStrategyMap(handlers);
        }

        Object handler = typeToHandlerMap.get(benefitsType.getCode());
        if (Objects.isNull(handler)) {

            throw new RuntimeException("获取到的福利类为null");
        }
        return (BenefitsHandler) handler;
    }

    private void initTypeToStrategyMap(BenefitsTypeEnum[] handlers) {

        typeToHandlerMap.clear();
        for (BenefitsTypeEnum handler : handlers) {

            try {
                Class<?> aClass = Class.forName(handler.getClazzName());
                Object bean = applicationContext.getBean(aClass);
                typeToHandlerMap.put(handler.getCode(), bean);
            } catch (ClassNotFoundException e) {
                log.error("福利Handler{}无法加载", handler.getCode(), e);
            }
        }
    }
}

(3)工厂涉及到的枚举类BenefitsTypeEnum:

package net.spo.enumerate;

import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Arrays;

/**
 * @description: 福利类型枚举
 * @author: Felix.Du
 * @date: 2021/10/13 3:51 下午
 */
@AllArgsConstructor
public enum BenefitsTypeEnum {

    /**
     * 注册成功
     */
    REGISTRATION_SUCCESS(1, "net.spo.handler.impl.RegistrationBenefitsHandler"),

    /**
     * 邀请好友
     */
    INVITE_FRIENDS(2,"net.spo.handler.impl.InviteFriendsBenefitsHandler"),

    /**
     * 添加官方客服
     */
    ADD_CUSTOMER_SERVICE_STAFF(3, "net.spo.handler.impl.BindCusServiceBenefitsHandler");

    @Getter
    private Integer code;

    /**
     * 全类名
     */
    @Getter
    private final String clazzName;

    public static BenefitsTypeEnum getBenefitsTypeByCode(Integer code){

        return Arrays
                .stream(BenefitsTypeEnum.values())
                .filter(benefitsTypeEnum -> code.equals(benefitsTypeEnum.getCode()))
                .findFirst()
                .get();

    }
}

3.模板搭建

我们通过福利类型传入工厂,能够拿到具体的策略处理器实体类,接下来就可以着手写模板方法了。
(1)福利处理器 BenefitsHandler 接口:

/**
 * @description: 福利处理器
 * @author: Felix.Du
 * @date: 2021/10/13 4:40 下午
 */
public interface BenefitsHandler {

    /**
     * 整个领奖流程,子类不需要实现
     *
     * @param userId 用户id
     * @param benefitsType 福利类型
     * @return 算力券/算力模板详情,用于领取后弹框
     */
    List<HashrateCouponAndTemplateVO> entireBenefitsProcess(Long userId, BenefitsTypeEnum benefitsType);

    /**
     * 判断当前用户是否满足福利所需条件(具体地判断逻辑方法需要子类实现)
     *
     * @param userId 用户id
     * @return true:完成; false:未完成
     */
    boolean checkWhetherMissionAccomplished(Long userId);

    /**
     * 领取福利,子类不需要实现
     *
     * @param userId 用户id
     * @param benefitsType 福利类型
     * @return 算力券/算力模板详情,用于领取后弹框
     */
    List<HashrateCouponAndTemplateVO> receiveBenefits(Long userId, BenefitsTypeEnum benefitsType);

    /**
     * 查询活动完成进度
     * key->进度编号, value->进度情况
     * @param userId  用户id
     * @return 活动完成进度,key->进度编号, value->进度情况
     */
    Map<String, String> getAccomplishedProgress(Long userId);

}

(2)抽象模板 AbstractBenefitsHandler :

/**
 * @description: 福利抽象类
 * @author: Felix.Du
 * @date: 2021/10/13 4:54 下午
 */
public abstract class AbstractBenefitsHandler implements BenefitsHandler {

    @Resource
    public MineUserBenefitsMarkMapper mineUserBenefitsMarkMapper;

    @Resource
    public RocketMQTemplate rocketMqTemplate;

    @Resource
    public MineHashrateCouponCustomerService mineHashrateCouponCustomerService;

    @Resource
    public MineHashrateTemplateCustomerService mineHashrateTemplateCustomerService;

    @Resource
    public CustomerClient customerClient;

    @Resource
    public MineHashrateTemplateService mineHashrateTemplateService;

    @Resource
    public MineHashrateTemplateCustomerMapper mineHashrateTemplateCustomerMapper;

    @Resource
    public MineHashrateCouponCustomerMapper mineHashrateCouponCustomerMapper;

    @Override
    public List<HashrateCouponAndTemplateVO> entireBenefitsProcess(Long userId, BenefitsTypeEnum benefitsType) {

        //查询是否已经领取该福利
        boolean whetherReceive = getBenefitsMark(userId, benefitsType);

        //已领取,返回错误提示
        AssertsUtil.isTrue(whetherReceive, ResultCode.BusinessCode.REPEAT_RECEIVE);

        //判断是否完成领取任务
        boolean whetherAccomplish = checkWhetherMissionAccomplished(userId);
        AssertsUtil.isFalse(whetherAccomplish, ResultCode.BusinessCode.UNFINISHED_TASK);

        //未领取且完成任务,直接领奖
        List<HashrateCouponAndTemplateVO> hashrateCouponAndTemplateVos = receiveBenefits(userId, benefitsType);

        AssertsUtil.isTrue(CollectionUtils.isEmpty(hashrateCouponAndTemplateVos), ResultCode.BusinessCode.RECEIVE_FAILED);

        //修改用户福利领取标识表
        updateUserMark(userId, benefitsType);

        return hashrateCouponAndTemplateVos;

    }


	/**
     * 领取福利,子类不需要实现
     *
     * @param userId 用户id
     * @param benefitsType 福利类型
     * @return 算力券/算力模板详情,用于领取后弹框
     */
    @Override
    public List<HashrateCouponAndTemplateVO> receiveBenefits(Long userId, BenefitsTypeEnum benefitsType) {

        CustomerWeChatInfoDTO cusInfo = customerClient.getWeChatInfo(userId).getData();

        Enumerate.DistributionsStatus distributionsStatus = getDistributionsStatusByBenefitsType(benefitsType);

        //获取可分配的算力模板和券
        var list = mineHashrateTemplateService.lambdaQuery()
                .eq(MineHashrateTemplate::getEnableStatus, Enumerate.IsEnable.ENABLE.getValue())
                .eq(MineHashrateTemplate::getDistributionsStatus, distributionsStatus.getCode())
                .list();
        //待分配模板
        var templateList = list
                .stream()
                .filter(item -> Objects.equals(item.getType(), HashrateTemplateEnum.TEMPLATE.getCode()))
                .map(item -> {
                    var templateCouponDTO = new TopTemplateCouponDTO();
                    templateCouponDTO.setId(item.getId());
                    templateCouponDTO.setReason(distributionsStatus.getReason());
                    var dto = new TopRewardDTO();
                    dto.setUserId(cusInfo.getId());
                    dto.setRegisterAccount(cusInfo.getRegisterAccount());
                    templateCouponDTO.setList(List.of(dto));
                    return templateCouponDTO;
                }).collect(Collectors.toList());
        //待分配劵
        var couponList = list
                .stream()
                .filter(item -> Objects.equals(item.getType(), HashrateTemplateEnum.COUPON.getCode()))
                .map(item -> {
                    var templateCouponDTO = new TopTemplateCouponDTO();
                    templateCouponDTO.setId(item.getId());
                    templateCouponDTO.setReason(distributionsStatus.getReason());
                    var dto = new TopRewardDTO();
                    dto.setUserId(cusInfo.getId());
                    dto.setRegisterAccount(cusInfo.getRegisterAccount());
                    templateCouponDTO.setList(List.of(dto));
                    return templateCouponDTO;
                }).collect(Collectors.toList());
        //分配模板
        var templateCustomerIdList = mineHashrateTemplateCustomerService.allocationHashrateTemplateByTop(templateList, new TopDurationDTO());
        List<HashrateCouponAndTemplateVO> oneTemplateCount1 = new ArrayList<>();
        List<HashrateCouponAndTemplateVO> oneTemplateCount2 = new ArrayList<>();
        AtomicLong atomicLong = new AtomicLong();
        if (!CollectionUtils.isEmpty(templateCustomerIdList)) {
            var queryWrapper = new QueryWrapper<>();
            queryWrapper.in("a.id", templateCustomerIdList);
            oneTemplateCount1 = mineHashrateTemplateCustomerMapper.selectPageHashrateTemplateCustomer(null, queryWrapper)
                    .stream()
                    .map(item -> {
                        //弹出算力券详情
                        HashrateCouponAndTemplateVO hashrateCouponAndTemplateVO = new HashrateCouponAndTemplateVO();
                        hashrateCouponAndTemplateVO.setName(item.getName());
                        hashrateCouponAndTemplateVO.setUnit(item.getUnit());
                        hashrateCouponAndTemplateVO.setHashrateType(item.getHashrateType());
                        hashrateCouponAndTemplateVO.setEachAmount(item.getEachAmount());
                        hashrateCouponAndTemplateVO.setValidity(item.getValidity());
                        hashrateCouponAndTemplateVO.setHashrateTemplateId(item.getId());
                        hashrateCouponAndTemplateVO.setId(atomicLong.addAndGet(1));
                        hashrateCouponAndTemplateVO.setType(HashrateTemplateEnum.TEMPLATE.getCode());
                        return hashrateCouponAndTemplateVO;
                    }).collect(Collectors.toList());

        }
        //分配劵
        var couponIdList = mineHashrateCouponCustomerService.allocationHashrateCouponByTop(couponList, new TopDurationDTO());
        if (!CollectionUtils.isEmpty(couponIdList)) {
            var queryWrapper = new QueryWrapper<>();
            queryWrapper.in("a.id", couponIdList);
            oneTemplateCount2 = mineHashrateCouponCustomerMapper.selectPageHashrateCouponCustomer(null, queryWrapper)
                    .stream()
                    .map(item -> {
                        //弹出算力券详情
                        HashrateCouponAndTemplateVO hashrateCouponAndTemplateVO = new HashrateCouponAndTemplateVO();
                        hashrateCouponAndTemplateVO.setName(item.getName());
                        hashrateCouponAndTemplateVO.setUnit(item.getUnit());
                        hashrateCouponAndTemplateVO.setHashrateType(item.getHashrateType());
                        hashrateCouponAndTemplateVO.setEachAmount(item.getEachAmount());
                        hashrateCouponAndTemplateVO.setValidity(item.getValidity());
                        hashrateCouponAndTemplateVO.setHashrateTemplateId(item.getId());
                        hashrateCouponAndTemplateVO.setId(atomicLong.addAndGet(1));
                        hashrateCouponAndTemplateVO.setType(HashrateTemplateEnum.COUPON.getCode());
                        return hashrateCouponAndTemplateVO;
                    }).collect(Collectors.toList());
        }
        oneTemplateCount1.addAll(oneTemplateCount2);
        return oneTemplateCount1;
    }

    /**
     * 根据用户id和福利类型查询是否已经领取该福利
     *
     * @param userId       用户id
     * @param benefitsType 福利类型
     * @return true:已领取; false:未领取
     */
    public boolean getBenefitsMark(Long userId, BenefitsTypeEnum benefitsType) {
        MineUserBenefitsMark mineUserBenefitsMark = mineUserBenefitsMarkMapper.selectOne(
                Wrappers
                        .lambdaQuery(MineUserBenefitsMark.class)
                        .eq(MineUserBenefitsMark::getUserId, userId)
                        .eq(MineUserBenefitsMark::getBenefitsTypeId, benefitsType.getCode()));

        //如果查询为空,说明还没领取,无创建记录
        if (Objects.isNull(mineUserBenefitsMark)) {
            return false;
        }

        return mineUserBenefitsMark.getMark() == UserMarkEnum.RECEIVED.getCode();
    }

    /**
     * 根据福利类型获取算力模板自动分配类型
     *
     * @param benefitsType 福利类型
     * @return 算力模板自动分配类型
     */
    public Enumerate.DistributionsStatus getDistributionsStatusByBenefitsType(BenefitsTypeEnum benefitsType) {

        Enumerate.DistributionsStatus distributionsStatus;
        switch (benefitsType) {
            case REGISTRATION_SUCCESS:
                distributionsStatus = Enumerate.DistributionsStatus.C_TRIGGER_REGISTER;
                break;
            case INVITE_FRIENDS:
                distributionsStatus = Enumerate.DistributionsStatus.C_TRIGGER_INVITE_FRIENDS;
                break;
            default:
                distributionsStatus = Enumerate.DistributionsStatus.C_TRIGGER_ADD_CUSTOMER_SERVICE;
                break;
        }
        return distributionsStatus;

    }

    /**
     * 领取成功后,修改用户福利领取标识
     *
     * @param benefitsType 福利类型
     */
    public void updateUserMark(Long userId, BenefitsTypeEnum benefitsType) {

        MineUserBenefitsMark mineUserBenefitsMark = mineUserBenefitsMarkMapper.selectOne(
                Wrappers
                        .lambdaQuery(MineUserBenefitsMark.class)
                        .eq(MineUserBenefitsMark::getUserId, userId)
                        .eq(MineUserBenefitsMark::getBenefitsTypeId, benefitsType.getCode())
        );

        //为空说明未领取,直接新增记录
        if(Objects.isNull(mineUserBenefitsMark)){

            MineUserBenefitsMark userBenefitsMark = new MineUserBenefitsMark();
            userBenefitsMark.setUserId(userId);
            userBenefitsMark.setBenefitsTypeId(Long.valueOf(benefitsType.getCode()));
            userBenefitsMark.setMark(UserMarkEnum.RECEIVED.getCode());

            mineUserBenefitsMarkMapper.insert(userBenefitsMark);
        }else {
            //不为空则修改状态
            mineUserBenefitsMark.setMark(UserMarkEnum.RECEIVED.getCode());
            mineUserBenefitsMarkMapper.updateById(mineUserBenefitsMark);
        }

    }
}

这里需要注意:AbstractBenefitsHandler福利模板需要去实现BenefitsHandler接口,抽象类可以选择实现接口的部分方法,这里就需要抽象类去实现抽象类的子类不实现的方法了。举个例子,比如说BenefitsHandler中有一个 判断当前用户是否满足福利所需条件 的方法checkWhetherMissionAccomplished(Long userId),很明显每福利的判断逻辑都不一样,这个需要子类自己去实现,写自己的逻辑,而模板父类不能关心子类的逻辑是如何的,这个时候模板类就不需要去实现这个方法了,而领取流程entireBenefitsProcess(Long userId, BenefitsTypeEnum benefitsType) 这个方法所有福利类型都是一样的逻辑,子类不会去关心,这个时候父类就需要去实现该方法,子类直接继承父类就行了。
(3)InviteFriendsBenefitsHandler 邀请好友福利处理器

@Component
@RequiredArgsConstructor
@Slf4j
public class InviteFriendsBenefitsHandler extends AbstractBenefitsHandler {

    private final CustomerActivityClient customerActivityClient;

    /**
     * 邀请好友个数要求
     */
    private static final Integer INVITE_LIMIT = 3;
    /**
     * 邀请好友实名认证个数限制
     */
    private static final Integer INVITE_KYC_LIMIT = 2;

    /**
     * 邀请好友需要:1 邀请3人;2 邀请好友完成实名认证3人;
     *
     * @param userId 用户id
     * @return 是否完成任务
     */
    @Override
    public boolean checkWhetherMissionAccomplished(Long userId) {

        //获取已邀请好友信息
        List<CustomerAccountDTO> invitedUsers = customerActivityClient.getInvitedUser(userId).getData();
        if (invitedUsers.size() < INVITE_LIMIT) {

            return Boolean.FALSE;
        }
        List<CustomerAccountDTO> kycUsers = invitedUsers
                .stream()
                .filter(u -> NumberUtil.equals(u.getKycStatus(), Enumerate.UserKycStatus.VERIFIED.getStatus()))
                .collect(Collectors.toList());
        if (kycUsers.size() < INVITE_KYC_LIMIT) {

            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    /**
     * 邀请好友需要:1 邀请3人;2 邀请好友完成实名认证3人;
     * @param userId 用户id
     * @return 活动完成进度,key->进度编号, value->进度情况
     */
    @Override
    public Map<String, String> getAccomplishedProgress(Long userId) {

        UUIDContext.setUUID(UUID.randomUUID());
        List<CustomerAccountDTO> invitedUsers = customerActivityClient.getInvitedUser(userId).getData();
        int invitedAmount = 0;
        int invitedKycAmount = 0;
        if (!CollUtil.isEmpty(invitedUsers)){

            invitedAmount = invitedUsers.size();
            List<CustomerAccountDTO> kycUsers = invitedUsers
                    .stream()
                    .filter(u -> NumberUtil.equals(u.getKycStatus(), Enumerate.UserKycStatus.VERIFIED.getStatus()))
                    .collect(Collectors.toList());
            invitedKycAmount = kycUsers.size();
        }

        String conditionInvite = invitedAmount + "/" + INVITE_LIMIT;
        String conditionKyc = invitedKycAmount + "/" + INVITE_KYC_LIMIT;

        Map<String, String> conditionMap = new HashMap<>(4);
        conditionMap.put(BenefitsConstants.CONDITION_1, conditionInvite);
        conditionMap.put(BenefitsConstants.CONDITION_2, conditionKyc);

        return Map.of(BenefitsConstants.CONDITION_1, invitedAmount + "/" + INVITE_LIMIT, 
                BenefitsConstants.CONDITION_2, invitedKycAmount + "/" + INVITE_KYC_LIMIT);
}

我们可以看到子类只需要去实现判断当前用户是否完成指定任务checkWhetherMissionAccomplished方法,以及获取完成进度getAccomplishedProgress方法。其他方法子类不需要关心,由父类统一处理。这样我们在遇到在增加一个福利类型的时候就很简单了,只需要增加一个具体的福利类型Strategy Handler,然后去继承模板父类AbstractBenefitsHandler,同时再去实现上诉两个方法即可。其他的什么是否已经领取过,然后再去判断是否完成任务,最后再去领取奖励,这些逻辑完全不用关心。
还有一点需要注意,如果业务上增加了一个流程不同的福利,你也可以通过继承模板父类,然后覆写他的方法即可实现。

新公司短短工作两个月,就遇到了两次需要使用这种模式的业务,所以决定记录一下,方便自己温故而知新。

看没看懂都点个赞呗。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我了解了您的问题。下面是我对这个问题的回答: 首先,我们需要了解一下策略模式工厂模式模板方法模式的概念和用法: - 策略模式:将一组算法封装起来,使它们可以互相替换,从而使得算法的变化不会影响到使用算法的客户端。在策略模式中,我们需要定义一个策略接口和具体的策略实现类。 - 工厂模式:将对象的创建与使用分离,通过工厂类来创建对象,从而使得客户端无需知道对象的具体实现。在工厂模式中,我们需要定义一个工厂接口和具体的工厂实现类。 - 模板方法模式:将一组相似的算法步骤封装起来,使得算法的变化只会影响到模板方法的具体实现,从而使得代码的复用性和可维护性更好。 在实现不同支付方式的接口时,我们可以使用策略模式来实现不同的支付策略工厂模式来创建不同的支付策略对象,模板方法模式来实现支付的公共流程。 具体实现步骤如下: 1. 定义支付策略接口 PaymentStrategy,其中包含一个 pay 方法用来实现支付功能。 ```java public interface PaymentStrategy { void pay(double amount); } ``` 2. 定义具体的支付策略实现类,例如 AlipayPaymentStrategy 和 WechatPaymentStrategy,实现 PaymentStrategy 接口中的 pay 方法。 ```java public class AlipayPaymentStrategy implements PaymentStrategy { @Override public void pay(double amount) { // 实现支付宝支付逻辑 System.out.println("使用支付宝支付:" + amount + "元"); } } public class WechatPaymentStrategy implements PaymentStrategy { @Override public void pay(double amount) { // 实现微信支付逻辑 System.out.println("使用微信支付:" + amount + "元"); } } ``` 3. 定义工厂接口 PaymentFactory,其中包含一个 createPayment 方法用来创建支付策略对象。 ```java public interface PaymentFactory { PaymentStrategy createPayment(); } ``` 4. 定义具体的支付工厂实现类,例如 AlipayPaymentFactory 和 WechatPaymentFactory,实现 PaymentFactory 接口中的 createPayment 方法。 ```java public class AlipayPaymentFactory implements PaymentFactory { @Override public PaymentStrategy createPayment() { return new AlipayPaymentStrategy(); } } public class WechatPaymentFactory implements PaymentFactory { @Override public PaymentStrategy createPayment() { return new WechatPaymentStrategy(); } } ``` 5. 定义支付模板类 PaymentTemplate,其中包含一个 pay 方法用来实现支付的公共流程,该方法调用 PaymentFactory 创建支付策略对象,并调用支付策略的 pay 方法实现支付功能。 ```java public abstract class PaymentTemplate { public void pay(double amount) { PaymentStrategy paymentStrategy = createPaymentStrategy(); paymentStrategy.pay(amount); } protected abstract PaymentStrategy createPaymentStrategy(); } ``` 6. 定义具体的支付模板类实现类,例如 AlipayPaymentTemplate 和 WechatPaymentTemplate,实现 PaymentTemplate 中的 createPaymentStrategy 方法,返回对应的支付策略对象。 ```java public class AlipayPaymentTemplate extends PaymentTemplate { @Override protected PaymentStrategy createPaymentStrategy() { return new AlipayPaymentFactory().createPayment(); } } public class WechatPaymentTemplate extends PaymentTemplate { @Override protected PaymentStrategy createPaymentStrategy() { return new WechatPaymentFactory().createPayment(); } } ``` 7. 在 SpringBoot 项目中使用支付模板类实现不同支付方式的接口,例如 PaymentController,其中包含一个 pay 方法用来接收支付请求,根据支付方式调用对应的支付模板类实现支付功能。 ```java @RestController public class PaymentController { @GetMapping("/pay") public String pay(@RequestParam("amount") double amount, @RequestParam("type") String type) { PaymentTemplate paymentTemplate = null; if ("alipay".equals(type)) { paymentTemplate = new AlipayPaymentTemplate(); } else if ("wechat".equals(type)) { paymentTemplate = new WechatPaymentTemplate(); } else { return "不支持的支付方式:" + type; } paymentTemplate.pay(amount); return "支付成功:" + amount + "元"; } } ``` 这样,我们就可以通过策略模式工厂模式模板方法模式来实现不同支付方式的接口,使得代码更加灵活、可维护性更好。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值