美团 手撕策略模式

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();
    }
}
相关推荐
智慧城市20306 小时前
183页PPT,麦肯锡战略屋品牌屋营销模型:打通战略、品牌与供应链的落地闭环
策略模式·战略咨询·流程管理
智慧城市20307 小时前
556页集团供应链、营销案例,从断裂到贯通:构建生产供应链、财务成本与营销数字化的四步战略落地闭环
策略模式
意法半导体STM3218 天前
【官方原创】如何为STM32CubeMX2配置Visual Studio Code配置方案
vscode·stm32·单片机·嵌入式硬件·策略模式·stm32cubemx·嵌入式开发
山东点狮信息科技有限公司19 天前
企业级 MES 制造执行系统架构设计与实践
spring cloud·性能优化·系统架构·策略模式·点狮
zzqssliu19 天前
基于策略模式与责任链的代购商品多源采集架构实战
架构·策略模式
mxpan20 天前
macOS 13+ 上使用 macFUSE + NTFS-3G 读写 NTFS 移动硬盘技术说明
macos·策略模式
折哥的程序人生 · 物流技术专研20 天前
Java 23 种设计模式:从踩坑到精通 | 番外:编排器+策略模式在多平台电子面单中的实战(含性能压测)
设计模式·策略模式·代码重构·java设计模式·编排器·电子面单·从踩坑到精通
忧云21 天前
2026年最新 Cursor 国内使用 DeepSeek API等各模型使用完整教程
ai编程·策略模式·cursor·byok·cursor使用国内大模型
AIex-YH21 天前
三域贯通11/12:生物制造的“死亡之谷“,CDMO 是桥还是船?
运维·制造·策略模式
回忆2012初秋22 天前
【Nginx】原理、配置与运维实战(2)
运维·nginx·策略模式