直接上代码,方便记忆。主要的要点,已经写到注释中。
一,代码展示
启动类
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
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());
}
}
策略接口
package com.rojer.factoryMoudle.impl.pay.inter;
import java.math.BigDecimal;
/**
* 策略模式接口
*/
public interface PaymentStrategy {
void pay(BigDecimal amount);
}
策略实现类
阿里支付类
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("进行了阿里支付");
}
}
银联支付类
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("进行了银联支付");
}
}
微信支付类
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("进行了微信支付");
}
}
简单工厂
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;
}
}
模板方法
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类
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;
}
}
package com.rojer.factoryMoudle.moudle;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class PayModule {
private Integer payType;
private BigDecimal payAmount;
}
二,代码测试
正常值场合
错误值场合
文章学自徐庶老师抖音小课知识讲解。