1.定义:策略模式是一种行为设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户。
2.核心组成:
(1)策略接口(Strategy):定义所有策略类必须实现的公共接口。
(2)具体策略(Concrete Strategy):实现策略接口,封装具体的算法或行为。
(3)上下文(Context):持有策略对象的引用,负责调用策略。
3.策略模式的优点:
(1)开闭原则:新增策略无需修改原有代码。
(2)避免多重条件判断:消除了大量的if-else或switch-case。
(3)提高可维护性:每种算法独立封装,便于理解和测试。
(4)运行时切换:可以在运行时动态改变对象的行为。
4.策略模式的缺点:
(1)策略类数量会增多。
(2)客户端需要了解不同策略的区别,选择合适的策略。
5.适用场景:
(1)系统有多种处理方式,需要动态选择。
(2)需要避免使用多重条件判断。
(3)算法经常变化或扩展。
附代码:
java
// 策略接口:付款策略
interface PaymentStrategy {
void pay(double amount);
}
// 信用卡付款策略实现类,用于创建信用卡支付对象
class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
private String cardHolder;
// 构造方法
public CreditCardPayment(String cardNumber, String cardHolder) {
this.cardNumber = cardNumber;
this.cardHolder = cardHolder;
}
// 成员方法
@Override
public void pay(double amount) {
System.out.printf("信用卡付款:%.2f元\n", amount);
System.out.println("卡号:" + cardNumber);
System.out.println("持卡人:" + cardHolder);
}
}
// 支付宝付款策略实现类,用于创建支付宝支付对象
class AlipayPayment implements PaymentStrategy {
private String account;
public AlipayPayment(String account) {
this.account = account;
}
@Override
public void pay(double amount) {
System.out.printf("支付宝付款:%.2f元\n", amount);
System.out.println("账号:" + account);
}
}
// 微信付款策略实现类,用于创建微信支付对象
class WechatPayment implements PaymentStrategy {
private String phoneNumber;
public WechatPayment(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
@Override
public void pay(double amount) {
System.out.printf("微信付款:%.2f元\n", amount);
System.out.println("手机号:" + phoneNumber);
}
}
// 现金付款策略实现类,用于创建现金支付对象
class CashPayment implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.printf("现金付款:%.2f元\n", amount);
System.out.println("请准备零钱");
}
}
// 上下文:订单
class Order {
// 订单金额
private double amount;
// 付款策略(接口类型),声明的接口类型,因此可以指向任何实现了PaymentStrategy的类(信用卡、支付宝、微信等)
private PaymentStrategy paymentStrategy;
// 构造方法:创建订单时传入金额,初始化amount
public Order(double amount) {
this.amount = amount;
}
// Setter方法,这是策略模式的核心,创建订单之后通过调用这个方法单独设置策略
// setPaymentStrategy方法要求传入一个PaymentStrategy类型的对象
public void setPaymentStrategy(PaymentStrategy strategy) {
// 把外部传入的策略对象存到当前订单对象内部
this.paymentStrategy = strategy;
}
// 执行方法
// 结账,调用策略对象的pay方法完成付款
public void checkout() {
System.out.println("订单金额:" + amount + "元");
// 调用这个对象的pay方法,并传入amount(订单金额)作为参数
// 由于paymentStrategy的类型是PaymentStrategy接口,而不是具体的类(如CreditCardPayment)
// 因此该变量可以指向任何实现类的对象
// 选择什么支付策略取决于main函数创建什么支付类型的对象
paymentStrategy.pay(amount);
System.out.println("付款成功!\n");
}
}
ACM模式:
java
import java.util.Scanner;
// 策略接口:付款策略
interface PaymentStrategy {
void pay(double amount);
}
// 信用卡付款策略实现类,用于创建信用卡支付对象
class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
private String cardHolder;
// 构造方法
public CreditCardPayment(String cardNumber, String cardHolder) {
this.cardNumber = cardNumber;
this.cardHolder = cardHolder;
}
// 成员方法
@Override
public void pay(double amount) {
System.out.printf("信用卡付款:%.2f元\n", amount);
System.out.println("卡号:" + cardNumber);
System.out.println("持卡人:" + cardHolder);
}
}
// 支付宝付款策略实现类,用于创建支付宝支付对象
class AlipayPayment implements PaymentStrategy {
private String account;
public AlipayPayment(String account) {
this.account = account;
}
@Override
public void pay(double amount) {
System.out.printf("支付宝付款:%.2f元\n", amount);
System.out.println("账号:" + account);
}
}
// 微信付款策略实现类,用于创建微信支付对象
class WechatPayment implements PaymentStrategy {
private String phoneNumber;
public WechatPayment(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
@Override
public void pay(double amount) {
System.out.printf("微信付款:%.2f元\n", amount);
System.out.println("手机号:" + phoneNumber);
}
}
// 现金付款策略实现类,用于创建现金支付对象
class CashPayment implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.printf("现金付款:%.2f元\n", amount);
System.out.println("请准备零钱");
}
}
// 上下文:订单
class Order {
// 订单金额
private double amount;
// 付款策略(接口类型),声明的接口类型,因此可以指向任何实现了PaymentStrategy的类(信用卡、支付宝、微信等)
private PaymentStrategy paymentStrategy;
// 构造方法:创建订单时传入金额,初始化amount
public Order(double amount) {
this.amount = amount;
}
// Setter方法,这是策略模式的核心,创建订单之后通过调用这个方法单独设置策略
// setPaymentStrategy方法要求传入一个PaymentStrategy类型的对象
public void setPaymentStrategy(PaymentStrategy strategy) {
// 把外部传入的策略对象存到当前订单对象内部
this.paymentStrategy = strategy;
}
// 执行方法
// 结账,调用策略对象的pay方法完成付款
public void checkout() {
System.out.println("订单金额:" + amount + "元");
// 调用这个对象的pay方法,并传入amount(订单金额)作为参数
// 由于paymentStrategy的类型是PaymentStrategy接口,而不是具体的类(如CreditCardPayment)
// 因此该变量可以指向任何实现类的对象
// 选择什么支付策略取决于main函数创建什么支付类型的对象
paymentStrategy.pay(amount);
System.out.println("付款成功!\n");
}
}
// 主类
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取订单金额
double amount = scanner.nextDouble();
// 创建一个新的订单对象
// 并调用Order类中的构造方法 public Order(double amount)
Order order = new Order(amount);
// 读取付款方式:1-信用卡,2-支付宝,3-微信,4-现金
int type = scanner.nextInt();
switch (type) {
case 1:
scanner.nextLine(); // 消耗换行符
String cardNumber = scanner.nextLine();
String cardHolder = scanner.nextLine();
// 创建一个信用卡支付对象
// 将创建的对象设置给订单
order.setPaymentStrategy(new CreditCardPayment(cardNumber, cardHolder));
break;
case 2:
scanner.nextLine();
String alipayAccount = scanner.nextLine();
// 创建一个支付宝支付对象
// 将创建的对象设置给订单
order.setPaymentStrategy(new AlipayPayment(alipayAccount));
break;
case 3:
scanner.nextLine();
String phoneNumber = scanner.nextLine();
// 创建一个微信支付对象
// 将创建的对象设置给订单
order.setPaymentStrategy(new WechatPayment(phoneNumber));
break;
case 4:
// 创建一个现金支付对象
// 将创建的对象设置给订单
order.setPaymentStrategy(new CashPayment());
break;
default:
System.out.println("无效的付款方式");
return;
}
order.checkout();
scanner.close();
}
}