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

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

一,代码展示

启动类

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;
}

二,代码测试

正常值场合

错误值场合

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

相关推荐
严文文-Chris1 小时前
【设计模式-享元】
android·java·设计模式
丶白泽2 小时前
重修设计模式-设计原则
设计模式·接口隔离原则·依赖倒置原则·开闭原则
【D'accumulation】2 小时前
典型的MVC设计模式:使用JSP和JavaBean相结合的方式来动态生成网页内容典型的MVC设计模式
java·设计模式·mvc
仙魁XAN4 小时前
Unity 设计模式 之 创造型模式-【工厂方法模式】【抽象工厂模式】
unity·设计模式·工厂方法模式·抽象工厂模式
龙哥·三年风水14 小时前
活动系统开发之采用设计模式与非设计模式的区别-后台功能总结
设计模式·php·tinkphp6
一头老羊14 小时前
前端常用的设计模式
设计模式
严文文-Chris15 小时前
【设计模式-组合】
设计模式
kimloner16 小时前
工厂模式(二):工厂方法模式
java·设计模式·工厂方法模式
丶白泽19 小时前
重修设计模式-结构型-桥接模式
java·设计模式·桥接模式
南郁20 小时前
把设计模式用起来!(3)用不好模式?之时机不对
设计模式