设计模式使用简例(简单工厂+策略模式+模板方法)

直接上代码,方便记忆。主要的要点,已经写到注释中。

一,代码展示

启动类

java 复制代码
package com.rojer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

controller

java 复制代码
package com.rojer.factoryMoudle.controller;

import com.rojer.factoryMoudle.PaymentStrategyFactory;
import com.rojer.factoryMoudle.impl.pay.AliPay;
import com.rojer.factoryMoudle.impl.pay.UnionPay;
import com.rojer.factoryMoudle.impl.pay.WechatPay;
import com.rojer.factoryMoudle.impl.pay.abs.AbstractPaymentStrategy;
import com.rojer.factoryMoudle.moudle.PayModule;
import com.rojer.factoryMoudle.impl.pay.inter.PaymentStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/")
public class PayController {

    @Autowired
    private PaymentStrategyFactory paymentStrategyFactory;

    /**
     * 普通写发法
     * @param module
     */
    @PostMapping("/online/pay1")
    public void pay(@RequestBody PayModule module) {
        PaymentStrategy paymentStrategy;
        switch (module.getPayType()) {
            case 1:
                paymentStrategy = new AliPay();
                break;
            case 2:
                paymentStrategy = new WechatPay();
                break;
            case 3:
                paymentStrategy = new UnionPay();
                break;
            default:
                throw new IllegalArgumentException("无效的支付类型");
        }
        paymentStrategy.pay(module.getPayAmount());
    }

    /**
     * 改造后写法
     * @param module
     */
    @PostMapping("/online/pay2")
    public void pay2(@RequestBody PayModule module) {
        AbstractPaymentStrategy strategy = paymentStrategyFactory.getPaymentStrategy(module.getPayType());
        strategy.commonPay(module.getPayAmount());
    }

}

策略接口

java 复制代码
package com.rojer.factoryMoudle.impl.pay.inter;

import java.math.BigDecimal;

/**
 * 策略模式接口
 */
public interface PaymentStrategy {
    void pay(BigDecimal amount);
}

策略实现类

阿里支付类

java 复制代码
package com.rojer.factoryMoudle.impl.pay;

import com.rojer.factoryMoudle.impl.pay.abs.AbstractPaymentStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

/**
 * 具体的策略实现AliPay
 */
@Component
public class AliPay extends AbstractPaymentStrategy {

    // 可注入别的类
    // @Autowired
    // private Pay pay;

    @Override
    public void pay(BigDecimal amount) {
        System.out.println("进行了阿里支付");
    }
}

银联支付类

java 复制代码
package com.rojer.factoryMoudle.impl.pay;

import com.rojer.factoryMoudle.impl.pay.abs.AbstractPaymentStrategy;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

/**
 * 具体的策略实现UnionPay
 */
@Component
public class UnionPay extends AbstractPaymentStrategy {

    // 可注入别的类
    // @Autowired
    // private Pay pay;

    @Override
    public void pay(BigDecimal amount) {
        System.out.println("进行了银联支付");
    }
}

微信支付类

java 复制代码
package com.rojer.factoryMoudle.impl.pay;

import com.rojer.factoryMoudle.impl.pay.abs.AbstractPaymentStrategy;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

/**
 * 具体的策略实现WechatPay
 */
@Component
public class WechatPay extends AbstractPaymentStrategy {

    // 可注入别的类
    // @Autowired
    // private Pay pay;

    @Override
    public void pay(BigDecimal amount) {
        System.out.println("进行了微信支付");
    }
}

简单工厂

java 复制代码
package com.rojer.factoryMoudle;

import com.rojer.factoryMoudle.impl.pay.AliPay;
import com.rojer.factoryMoudle.impl.pay.UnionPay;
import com.rojer.factoryMoudle.impl.pay.WechatPay;
import com.rojer.factoryMoudle.impl.pay.abs.AbstractPaymentStrategy;
import com.rojer.factoryMoudle.moudle.PayEnum;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * 设计模式之简单工厂
 */
@Component
public class PaymentStrategyFactory implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    /**
     * 使用简单工厂生成具体的支付对学校
     *
     * @param payType 支付类型
     * @return AbstractPaymentStrategy 抽象支付类
     */
    public AbstractPaymentStrategy getPaymentStrategy(Integer payType) {
        if (PayEnum.ALIPAY.getCode() == payType) {
            return applicationContext.getBean(AliPay.class);
        } else if (PayEnum.WECHATPAY.getCode() == payType){
            return applicationContext.getBean(WechatPay.class);
        } else if (PayEnum.UNIONPAY.getCode() == payType) {
            return applicationContext.getBean(UnionPay.class);
        } else {
            throw new IllegalArgumentException("无效的支付类型");
        }
    }

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

模板方法

java 复制代码
package com.rojer.factoryMoudle.impl.pay.abs;

import com.rojer.factoryMoudle.impl.pay.inter.PaymentStrategy;

import java.math.BigDecimal;

/**
 * 设计模式之模板方法
 * 定义了支付的模板方法
 */
public abstract class AbstractPaymentStrategy implements PaymentStrategy {

    // 模板方法
    public final void commonPay(BigDecimal amount) {
        // 检测金额未合法数字
        check(amount);

        // 扩展支付
        pay(amount);

        // 可以继续扩展模板
    }

    // 声明未private,该方法不可被重写,必须按这个进行
    private void check(BigDecimal amount) {
        if (amount.compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("无效的金额!");
        }
    }
}

module类

java 复制代码
package com.rojer.factoryMoudle.moudle;

public enum PayEnum {
    ALIPAY(1, "Alipay"),
    WECHATPAY(2, "WeChat Pay"),
    UNIONPAY(3, "UnionPay");

    private final int code;
    private final String description;

    PayEnum(int code, String description) {
        this.code = code;
        this.description = description;
    }

    public int getCode() {
        return code;
    }

    public String getDescription() {
        return description;
    }

}
java 复制代码
package com.rojer.factoryMoudle.moudle;

import lombok.Data;

import java.math.BigDecimal;

@Data
public class PayModule {

    private Integer payType;

    private BigDecimal payAmount;
}

二,代码测试

正常值场合

错误值场合

文章学自徐庶老师抖音小课知识讲解。

相关推荐
冷崖8 小时前
工厂模式-创建型
c++·设计模式
何中应12 小时前
【面试题-5】设计模式
java·开发语言·后端·设计模式·面试题
沐森16 小时前
在实战中运用泛型和动态trait(特质)
设计模式
lomocode17 小时前
改一个需求动 23 处代码?你可能踩进了这个坑
后端·设计模式
喷火龙8号18 小时前
JWT 认证方案深度对比:单 Token 扩展刷新 vs 双 Token 验证
后端·设计模式·架构
fakerth1 天前
【OpenHarmony】设计模式模块详解
c++·单例模式·设计模式·openharmony
alibli2 天前
一文学会设计模式之创建型模式及最佳实现
c++·设计模式
1024肥宅2 天前
前端常用模式:提升代码质量的四大核心模式
前端·javascript·设计模式
郝学胜-神的一滴2 天前
设计模式依赖于多态特性
java·开发语言·c++·python·程序人生·设计模式·软件工程
帅次2 天前
系统分析师:软件需求工程的软件需求概述、需求获取、需求分析
设计模式·重构·软件工程·团队开发·软件构建·需求分析·规格说明书