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

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

一,代码展示

启动类

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

二,代码测试

正常值场合

错误值场合

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

相关推荐
wu~9702 小时前
手撕四种常用设计模式(工厂,策略,代理,单例)
java·单例模式·设计模式·代理模式·抽象工厂模式·策略模式
敲代码的 蜡笔小新8 小时前
【行为型之访问者模式】游戏开发实战——Unity灵活数据操作与跨系统交互的架构秘诀
unity·设计模式·c#·访问者模式
软考真题app1 天前
软件设计师考试结构型设计模式考点全解析
设计模式·软件设计师·结构型设计模式·考试考点
xiaolin03331 天前
【设计模式】- 行为型模式1
设计模式·状态模式·责任链模式·策略模式·命令模式·模板方法模式·行为型模式
沐土Arvin1 天前
深入理解 requestIdleCallback:浏览器空闲时段的性能优化利器
开发语言·前端·javascript·设计模式·html
bao_lanlan1 天前
兰亭妙微:用系统化思维重构智能座舱 UI 体验
ui·设计模式·信息可视化·人机交互·交互·ux·外观模式
总是难免1 天前
设计模式 - 单例模式 - Tips
java·单例模式·设计模式
Java致死1 天前
设计模式Java
java·开发语言·设计模式
ghost1432 天前
C#学习第23天:面向对象设计模式
开发语言·学习·设计模式·c#
西北大程序猿2 天前
日志与策略模式
策略模式