开闭原则,什么是开闭原则?

本文介绍了面向对象编程中的一个重要原则——开闭原则。该原则强调在软件设计时应尽量通过增加新模块来实现新功能,而非修改原有代码。遵循这一原则有助于提高代码的复用性和便于后期维护。

开闭原则,什么是开闭原则?


开闭原则是面向对象编程中,一个很重要的原则。

开闭原则:程序开放拓展,但是封闭修改。

简单来说就是,要实现一个新功能,尽量去添加一个新的模块(开放拓展),而不是去修改原有的代码(封闭修改)。


使用开闭原则的好处

  • 提高代码的复用性
  • 以便程序后期维护
# 🎯 开闭原则(Open/Closed Principle)详解 ## 一、什么是开闭原则? **开闭原则**是面向对象设计的五大基本原则(SOLID)之一,由Bertrand Meyer提出。 > **“对扩展开放,对修改关闭”** > > Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. 简单来说: - ✅ 允许通过**增加新代码**来扩展功能 - ❌ 不允许**修改已有代码**来实现新需求 ## 二、核心思想解析 ### 1. 对扩展开放 - 系统应该能够通过添加新的类、模块或组件来增加新功能 - 新增代码不会影响现有功能 ### 2. 对修改关闭 - 已经测试通过的现有代码不应该被修改 - 避免因修改引入新的bug ## 三、在咖啡厅项目中的完美体现 让我们通过具体的代码场景来理解这个原则。 ### 场景:需要新增"微信支付"功能 #### ❌ 违反开闭原则的做法(直接修改现有代码) ```cpp // 修改原有的支付处理逻辑 void processPayment(int paymentType, double amount) { switch(paymentType) { case 1: // 现金 cout << "现金支付"; break; case 2: // 信用卡 cout << "信用卡支付"; break; case 3: // 支付宝 cout << "支付宝支付"; break; // 👇 直接在这里添加新case - 违反了"对修改关闭" case 4: // 微信支付 - 直接修改原有函数! cout << "微信支付"; break; } } ``` **问题:** - 修改了已经稳定的代码 - 可能意外破坏原有功能 - 每次新增支付方式都要改这里 #### ✅ 符合开闭原则的做法(使用策略模式+工厂模式) ```cpp // 1. 新增微信支付类(扩展,不修改) class WeChatPayment : public PaymentStrategy { public: void pay(double amount) override { cout << "📱 微信扫码支付 ¥" << amount << endl; } string getName() const override { return "微信支付"; } }; // 2. 只需修改工厂(这是允许的,因为工厂就是用来管理创建的) class PaymentFactory { public: static unique_ptr<PaymentStrategy> create(int type, const string& card = "") { switch (type) { case 1: return make_unique<CashPayment>(); case 2: return make_unique<CreditCardPayment>(card); case 3: return make_unique<AlipayPayment>(); // 👍 在工厂中添加新case - 这是"扩展" case 4: return make_unique<WeChatPayment>(); default: throw invalid_argument("无效类型"); } } }; ``` **优势:** - `PaymentStrategy` 接口不需要修改 - 已有的 `CashPayment`、`CreditCardPayment` 等类保持不变 - 主业务流程完全不受影响 ### 四、另一个例子:新增"会员折扣"功能 #### ✅ 符合开闭原则的实现 ```cpp // 1. 创建折扣策略接口 class DiscountStrategy { public: virtual ~DiscountStrategy() = default; virtual double applyDiscount(double originalPrice) = 0; virtual string getDescription() const = 0; }; // 2. 实现普通客户(无折扣) class RegularCustomer : public DiscountStrategy { public: double applyDiscount(double price) override { return price; } string getDescription() const override { return "普通客户"; } }; // 3. 实现会员客户(9折) class MemberCustomer : public DiscountStrategy { public: double applyDiscount(double price) override { return price * 0.9; } string getDescription() const override { return "会员客户(9折)"; } }; // 4. 实现VIP客户(8折) class VIPCustomer : public DiscountStrategy { public: double applyDiscount(double price) override { return price * 0.8; } string getDescription() const override { return "VIP客户(8折)"; } }; // 5. 客户端使用(完全不知道具体类型) class OrderProcessor { private: unique_ptr<DiscountStrategy> discountStrategy; public: OrderProcessor(unique_ptr<DiscountStrategy> strategy) : discountStrategy(move(strategy)) {} void processOrder(double originalPrice) { double finalPrice = discountStrategy->applyDiscount(originalPrice); cout << "原价: ¥" << originalPrice << ", 折后: ¥" << finalPrice << " (" << discountStrategy->getDescription() << ")" << endl; } }; ``` **当需要新增"学生折扣":** ```cpp // 只需新增一个类,完全不修改现有代码 class StudentDiscount : public DiscountStrategy { public: double applyDiscount(double price) override { return price * 0.85; } string getDescription() const override { return "学生优惠(85折)"; } }; ``` ## 五、开闭原则带来的好处 | 好处 | 说明 | |------|------| | **稳定性** | 核心业务逻辑稳定,不会因新增功能而崩溃 | | **可维护性** | Bug修复和功能扩展互不影响 | | **可测试性** | 新功能独立测试,不影响原有测试用例 | | **团队协作** | 多个开发者可以行开发新功能 | | **降低风险** | 避免"修一个bug,出三个新bug" | ## 六、如何识别违反开闭原则的代码? 以下迹象表明可能违反了开闭原则: ```cpp // 1. 大量的switch/case语句 switch(type) { case TYPE_A: /* ... */ break; case TYPE_B: /* ... */ break; // 每新增type都要修改这里 } // 2. 类型检查 if (obj instanceof ClassA) { /* ... */ } else if (obj instanceof ClassB) { /* ... */ } // 3. 配置文件中需要手动添加映射 // config.json: {"types": ["A", "B", "C"]} // 新增D要改配置 ``` ## 七、实现开闭原则的关键技术 ### 1. 多态(Polymorphism) ```cpp vector<unique_ptr<PaymentStrategy>> strategies; strategies.push_back(make_unique<CashPayment>()); strategies.push_back(make_unique<WeChatPayment>()); // 新增无需改前面代码 ``` ### 2. 依赖注入(Dependency Injection) ```cpp // 通过构造函数注入策略 OrderProcessor processor(make_unique<MemberCustomer>()); ``` ### 3. 工厂模式 ```cpp // 工厂封装了对象创建的复杂性 auto strategy = PaymentFactory::create(paymentType); ``` ### 4. 接口隔离 ```cpp // 定义清晰的契约 class PaymentStrategy { virtual void pay(double amount) = 0; }; ``` ## 八、实际开发中的应用建议 1. **提前规划可变点**:识别系统中可能变化的部分 2. **抽象先行**:先定义接口,再实现细节 3. **小步迭代**:每次只扩展一点点 4. **重构机**:当发现需要频繁修改同一段代码,考虑重构为开闭原则设计 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值