Java 策略模式简单实现

Java策略模式(Strategy Pattern)

策略模式是一种设计模式,它允许在运行时根据需要选择算法。

一:接口和类的组合来实现策略模式

以下是一个简单的 Java 示例,演示了如何使用策略模式:

// 定义一个策略接口
interface PaymentStrategy {
    void pay(int amount);
}

// 不同的支付策略实现
class CreditCardPayment implements PaymentStrategy {
    private String cardNumber;
    private String cvv;
    private String expiryDate;

    public CreditCardPayment(String cardNumber, String cvv, String expiryDate) {
        this.cardNumber = cardNumber;
        this.cvv = cvv;
        this.expiryDate = expiryDate;
    }

    @Override
    public void pay(int amount) {
        // 实现信用卡支付逻辑
        System.out.println(amount + " paid with credit card");
    }
}

class AliPayPayment implements PaymentStrategy {
    private String email;
    private String password;

    public AliPayPayment(String email, String password) {
        this.email = email;
        this.password = password;
    }

    @Override
    public void pay(int amount) {
        // 实现支付宝支付逻辑
        System.out.println(amount + " paid with PayPal");
    }
}

// 上下文类,用于设置和应用策略
class PaymentContext {
    private PaymentStrategy paymentStrategy;

    public PaymentContext(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }

    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }

    public void pay(int amount) {
        paymentStrategy.pay(amount);
    }
}

// 示例使用
public class StrategyPatternExample {
    public static void main(String[] args) {
        PaymentContext paymentContext = new PaymentContext(new CreditCardPayment("1234 5678 9012 3456", "123", "12/25"));
        
        paymentContext.pay(100); // 使用信用卡支付 100
        
        paymentContext.setPaymentStrategy(new PayPalPayment("example@example.com", "password123"));
        paymentContext.pay(50); // 使用 PayPal 支付 50
    }
}

PaymentStrategy 接口定义了支付策略的契约,然后 CreditCardPayment 和 PayPalPayment 类分别实现了这个接口。PaymentContext 类用于设置和应用不同的支付策略。在示例的 main 方法中,首先使用信用卡支付了 100,然后切换到 PayPal 支付方式支付了 50。

二:工厂模式+策略模式

PaymentContext 中需要持有一个PaymentStrategy ,在实际的应用场景中,可以使用工厂模式,管理PaymentStrategy 的所有实例对象,然后根据业务需求,从工厂中获取。

//支付工厂
class PaymentFactory {
    public static PaymentStrategy createPaymentStrategy(String paymentType) {
        switch (paymentType) {
            case "creditcard":
                return new CreditCardPayment();
            case "paypal":
                return new PayPalPayment();
            // 可以添加更多的支付类型
            default:
                throw new IllegalArgumentException("Unknown payment type: " + paymentType);
        }
    }
}
// 示例使用
public class FactoryStrategyPatternExample {
    public static void main(String[] args) {   
        // 根据不同的类型创建对应的策略对象
        PaymentStrategy creditCardPayment = PaymentFactory.createPaymentStrategy("creditcard");
        PaymentStrategy paypalPayment = PaymentFactory.createPaymentStrategy("paypal");

        int amount = 100;

        // 使用不同的策略对象进行支付
        creditCardPayment.pay(amount); // 使用信用卡支付 100
        paypalPayment.pay(amount); // 使用 PayPal 支付 100
    }
}

三:枚举类实现策略模式

在Java中,枚举类(Enum)是一种特殊的数据类型,它允许你定义一组命名的常量。
通过在Enum中添加一个抽象方法,用来实现策略模式。

// 定义一个枚举表示不同的支付策略
enum PaymentType {
    CREDIT_CARD {
        @Override
        public void pay(int amount) {
            // 实现信用卡支付逻辑
            System.out.println(amount + " paid with credit card");
        }
    },
    PAYPAL {
        @Override
        public void pay(int amount) {
            // 实现PayPal支付逻辑
            System.out.println(amount + " paid with PayPal");
        }
    },
    // 可以添加更多的支付策略...

    // 默认实现,可以选择抛出异常或者提供一个默认的逻辑
    DEFAULT {
        @Override
        public void pay(int amount) {
            throw new UnsupportedOperationException("Unknown or unspecified payment type");
            // 或者提供一个默认的支付逻辑
            // System.out.println("Unsupported payment type");
        }
    };

    // 抽象方法,每个枚举值都需要实现它
    public abstract void pay(int amount);
}

// 示例使用
public class EnumStrategyPatternExample {
    public static void main(String[] args) {
        int amount = 100;

        PaymentType.CREDIT_CARD.pay(amount); // 使用信用卡支付 100
        PaymentType.PAYPAL.pay(amount); // 使用 PayPal 支付 100

        // 测试未知支付类型
        PaymentType.UNKNOWN.pay(amount);
    }
}

上面代码示例中,在controller或service层,并不能使用参数选择某一个支付方式;所以,我们需要给枚举类添加一些属性,方便我们获取枚举对象;添加一个doPay方法,用于外部统一调用。

import lombok.Getter;
import java.util.HashMap;
import java.util.Map;

@Getter
public enum PaymentType {
    CREDIT_CARD(1, "信用卡支付") {
        @Override
        public void pay(int amount) {
            // 实现信用卡支付逻辑
            System.out.println(amount + " paid with credit card");
        }
    },
    PAYPAL(2, "PayPal支付") {
        @Override
        public void pay(int amount) {
            // 实现PayPal支付逻辑
            System.out.println(amount + " paid with PayPal");
        }
    },
    // 可以添加更多的支付策略...

    // 默认实现,可以选择抛出异常或者提供一个默认的逻辑
    DEFAULT(0, "未知方式") {
        @Override
        public void pay(int amount) {
        	//抛出一个异常
            throw new Exception("Unknown or unspecified payment type");
            // 或者提供一个默认的支付逻辑
            // System.out.println("Unsupported payment type");
        }
    };
    //支付方式编码
    private Integer payTypeCode;
    //支付方式名称
    private String payTypeName;

    PaymentType(Integer payTypeCode, String payTypeName) {
        this.payTypeCode = payTypeCode;
        this.payTypeName = payTypeName;

    }

    private static final Map<Integer, PaymentType> dataMap = new HashMap<>();

    static {
        for (PaymentType paymentType : PaymentType.values()) {
            dataMap.put(paymentType.getPayTypeCode(), paymentType);
        }
    }

    // 抽象方法,每个枚举值都需要实现它
    public abstract void pay(int amount);
	//外部调用的方法
    public static void doPay(Integer payTypeCode, int amount) {
        dataMap.get(payTypeCode).pay(amount);
    }
}

// 示例使用
public class EnumStrategyPatternExample {
    public static void main(String[] args) {
        int amount = 100;
        PaymentType.doPay(1,amount); // 使用信用卡支付 100
        PaymentType.doPay(2,amount); // 使用 PayPal 支付 100
        // 测试未知支付类型
        PaymentType.doPay(0,amount);
    }
}

在实际应用场景中,PaymentType.pay()方法中,根据前端或者方法调用者,传入支付方式和支付金额即可。

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值