Java设计模式 | 基于订单批量支付场景,对策略模式和简单工厂模式进行简单实现

基于订单批量支付场景,对策略模式和简单工厂模式进行简单实现

策略模式

介绍

以下是菜鸟教程对策略模式的介绍: 策略模式

在策略模式定义了一系列算法或策略,并将每个算法封装在独立的类中,使得它们可以互相替换。通过使用策略模式,可以在运行时根据需要选择不同的算法,而不需要修改客户端代码。

策略模式主要有三个角色:

  • 抽象策略(Abstract Strategy):定义了策略对象的公共接口或抽象类,规定了具体策略类必须实现的方法。
  • 具体策略(Concrete Strategy):实现了抽象策略定义的接口或抽象类,包含了具体的算法实现。
  • 环境(Context):维护一个对策略对象的引用,负责将客户端请求委派给具体的策略对象执行。环境类可以通过依赖注入、简单工厂等方式来获取具体策略对象。

实现

抽象策略

我们使用接口来实现抽象策略,规定了支付的公共方法,根据传入的用户名和支付金额进行结算。

package knowledege.designPattern.strategy.test1;

import java.math.BigDecimal;

public interface PayStrategy {
    void pay(String name, BigDecimal money);
}

具体策略

初始化微信和支付宝两种支付策略

1.AliPayStrategy
package knowledege.designPattern.strategy.test1;

import java.math.BigDecimal;

public class AliPayStrategy implements PayStrategy{
    @Override
    public void pay(String name, BigDecimal money) {
        System.out.println("[" +name+ "]使用支付宝支付..." + money + "元");
    }
}
2.WeChatPayStrategy
package knowledege.designPattern.strategy.test1;

import java.math.BigDecimal;

public class WeChatPayStrategy implements PayStrategy{
    @Override
    public void pay(String name, BigDecimal money) {
        System.out.println("[" +name+ "]使用微信支付..." + money + "元");
    }
}

环境

提供设置策略和执行策略的方法

package knowledege.designPattern.strategy.test1;

import java.math.BigDecimal;
public class PayContext {
    private PayStrategy payStrategy;
    public PayContext(){}
    public void setPayStrategy(PayStrategy payStrategy){
        this.payStrategy = payStrategy;
    }
    public void executePayStrategy(String name, BigDecimal money){
        payStrategy.pay(name, money);
    }
}

使用简单工厂来获取具体策略对象

支付方式枚举

定义枚举并支持静态根据支付方式获取枚举

package knowledege.designPattern.strategy.test1;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum PayWayEnum {

    PAY_ALI("01","支付宝"),
    PAY_WE_CHAT("02","微信");
    public final String payWay;
    public final String payDesc;

    public static PayWayEnum getEnumByWay(String payWay){
        for(PayWayEnum enums: PayWayEnum.values()){
            if(enums.payWay.equals(payWay)){
                return enums;
            }
        }
        return null;
    }
}

策略工厂接口


public interface StrategyFactory {
    PayStrategy initStrategy();
}

策略工厂实现

package knowledege.designPattern.strategy.test1;

import java.util.Objects;

public class StrategySimpleFactory {
    public static PayStrategy initStrategy(String payWay){
        PayWayEnum payWayEnum = PayWayEnum.getEnumByWay(payWay);
        if (Objects.isNull(payWayEnum)) {
            return null;
        }
        PayStrategy strategy = null;
        switch (payWayEnum) {
            case PAY_ALI:
                strategy = new AliPayStrategy();
                break;
            case PAY_WE_CHAT:
                strategy = new WeChatPayStrategy();
                break;
        }
        return strategy;
    }
}

测试使用

订单实体类

package knowledege.designPattern.strategy.test1;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OrderTestDTO {
    Integer orderNum;
    String payPersonName;
    String payWay;
    BigDecimal payMoney;
}

对订单进行批量支付

模拟对订单进行批量支付

  • 模拟获取一批订单
  • 循环订单进行支付
    • 根据订单的支付方式,获取支付枚举
    • 根据枚举,使用工厂模式获取支付策略
    • 根据策略,使用支付环境进行支付
package knowledege.designPattern.strategy.test1;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class test1 {
    public static void main(String[] args) {
        List<OrderTestDTO> orderList = initOrders();
        batchPay(orderList);
    }

    /**
     * 获取订单
     */
    public static  List<OrderTestDTO> initOrders(){
        List<OrderTestDTO> orderList = new ArrayList<>();
        orderList.add(new OrderTestDTO(1,"aaa","01",new BigDecimal("99")));
        orderList.add(new OrderTestDTO(2,"aaa","02",new BigDecimal("20")));
        orderList.add(new OrderTestDTO(3,"bbb","01",new BigDecimal("17")));
        orderList.add(new OrderTestDTO(4,"ccc","02",new BigDecimal("19.88")));

        return orderList;
    }

    /**
     * 订单批量支付
     */
    public static void batchPay(List<OrderTestDTO> orderList){
        PayContext payContext = new PayContext();
        orderList.forEach( order -> {
            PayStrategy strategy = StrategySimpleFactory.initStrategy(order.getPayWay());
            payContext.setPayStrategy(strategy);
            payContext.executePayStrategy(order.getPayPersonName(), order.getPayMoney());
        });
    }
}

结果

可以看到每笔订单都成功根据其支付方式支付了。
在这里插入图片描述

扩展一种支付方式:银行卡支付

如果需要扩展一种支付方式,才能看出策略+工厂模式的真正优点。
下面我们模拟扩展一种支付方式:银行卡支付

支付策略新增

package knowledege.designPattern.strategy.test1;

import java.math.BigDecimal;

public class CardStrategy implements PayStrategy{

    @Override
    public void pay(String name, BigDecimal money) {
        System.out.println("[" +name+ "]使用银行卡支付..." + money + "元");
    }
}

支付枚举新增

PAY_CARD("03","银行卡"),

工厂新增生产银行卡

            case PAY_CARD:
                strategy = new CardStrategy();
                break;

重新测试

在这里插入图片描述
成功适配了银行卡支付,改动较少,又没有更改核心的支付逻辑,符合开闭原则!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
下面是一个 Java 实现工厂模式、单例模式、策略模式、建造者模式多个设计模式的组合示例: 1. 工厂模式(Factory Pattern) ```java public interface Animal { void eat(); } public class Cat implements Animal { @Override public void eat() { System.out.println("Cat is eating!"); } } public class Dog implements Animal { @Override public void eat() { System.out.println("Dog is eating!"); } } public class AnimalFactory { public static Animal createAnimal(String type) { if ("cat".equalsIgnoreCase(type)) { return new Cat(); } else if ("dog".equalsIgnoreCase(type)) { return new Dog(); } else { throw new IllegalArgumentException("Invalid animal type: " + type); } } } ``` 2. 单例模式(Singleton Pattern) ```java public class Singleton { private static final Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton getInstance() { return INSTANCE; } public void showMessage() { System.out.println("Hello, Singleton!"); } } ``` 3. 策略模式(Strategy Pattern) ```java public interface DiscountStrategy { double getDiscount(double originalPrice); } public class FixedDiscountStrategy implements DiscountStrategy { private double discount; public FixedDiscountStrategy(double discount) { this.discount = discount; } @Override public double getDiscount(double originalPrice) { return originalPrice - discount; } } public class PercentageDiscountStrategy implements DiscountStrategy { private double percentage; public PercentageDiscountStrategy(double percentage) { this.percentage = percentage; } @Override public double getDiscount(double originalPrice) { return originalPrice * (1 - percentage); } } public class ShoppingCart { private List<Double> items; private DiscountStrategy strategy; public ShoppingCart(DiscountStrategy strategy) { this.strategy = strategy; this.items = new ArrayList<>(); } public void addItem(double price) { items.add(price); } public double calculateTotal() { double sum = 0; for (Double price : items) { sum += price; } return strategy.getDiscount(sum); } } ``` 4. 建造者模式(Builder Pattern) ```java public class User { private String firstName; private String lastName; private int age; private String email; private User(Builder builder) { this.firstName = builder.firstName; this.lastName = builder.lastName; this.age = builder.age; this.email = builder.email; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public int getAge() { return age; } public String getEmail() { return email; } @Override public String toString() { return "User{" + "firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + ", age=" + age + ", email='" + email + '\'' + '}'; } public static class Builder { private String firstName; private String lastName; private int age; private String email; public Builder(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public Builder age(int age) { this.age = age; return this; } public Builder email(String email) { this.email = email; return this; } public User build() { return new User(this); } } } ``` 以上是四种设计模式的示例,我们可以将它们组合起来使用,例如: ```java public class Application { public static void main(String[] args) { // 工厂模式 Animal cat = AnimalFactory.createAnimal("cat"); Animal dog = AnimalFactory.createAnimal("dog"); cat.eat(); dog.eat(); // 单例模式 Singleton singleton = Singleton.getInstance(); singleton.showMessage(); // 策略模式 DiscountStrategy fixedDiscount = new FixedDiscountStrategy(10); DiscountStrategy percentageDiscount = new PercentageDiscountStrategy(0.2); ShoppingCart cart = new ShoppingCart(percentageDiscount); cart.addItem(100); cart.addItem(200); System.out.println("Total price after discount: " + cart.calculateTotal()); // 建造者模式 User user = new User.Builder("John", "Doe") .age(30) .email("john.doe@example.com") .build(); System.out.println(user); } } ``` 通过组合多种设计模式,我们可以更好地解决复杂的问题,提高代码的可维护性和可扩展性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小雅痞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值