欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > SOLID——依赖倒置原则

SOLID——依赖倒置原则

2024/10/24 22:29:02 来源:https://blog.csdn.net/qq_68194402/article/details/141307643  浏览:    关键词:SOLID——依赖倒置原则

依赖倒置原则

      • 依赖倒置原则
      • 原始代码分析
      • 违背依赖倒置原则的点
      • 改进建议
        • 使用工厂模式的示例
      • 实际应用场景
      • 结合其他设计原则
      • 可能的误区
      • 总结

依赖倒置原则

依赖倒置原则(Dependency Inversion Principle, DIP)是 SOLID 原则中的一部分,旨在减少模块之间的耦合度。高耦合度会导致系统难以维护和扩展。遵循 DIP 可以使系统更易于测试、重用和修改,特别是在大型项目中,能够显著提高代码的灵活性和可维护性。该原则主要强调:

  • 高层模块不应依赖于低层模块:高层模块(业务逻辑)不应直接依赖于低层模块(具体实现)。
  • 二者都应依赖于抽象:高层和低层模块都应该依赖于抽象,而不是具体的实现细节。

原始代码分析

以下是一个使用策略模式的原始代码示例,但存在依赖倒置原则的违反:

#include <iostream>
#include <vector>// 策略接口
class SortStrategy
{
public:virtual void sort(std::vector<int>& arr) = 0; // 策略接口
};// 具体策略:冒泡排序
class BubbleSort : public SortStrategy {
public:void sort(std::vector<int>& arr) override {for (size_t i = 0; i < arr.size() - 1; ++i) {for (size_t j = 0; j < arr.size() - i - 1; ++j) {if (arr[j] > arr[j + 1]) {std::swap(arr[j], arr[j + 1]);}}}}
};// 具体策略:快速排序
class QuickSort : public SortStrategy {
public:void sort(std::vector<int>& arr) override {quickSort(arr, 0, arr.size() - 1);}private:void quickSort(std::vector<int>& arr, int low, int high) {if (low < high) {int pivot = arr[high];int i = low - 1;for (int j = low; j < high; ++j) {if (arr[j] < pivot) {++i;std::swap(arr[i], arr[j]);}}std::swap(arr[i + 1], arr[high]);quickSort(arr, low, i);quickSort(arr, i + 2, high);}}
};// 上下文类
class Sorter {
private:SortStrategy* strategy;public:Sorter(SortStrategy* strategy) : strategy(strategy) {}void setStrategy(SortStrategy* strategy) {this->strategy = strategy;}void sort(std::vector<int>& arr) {strategy->sort(arr);}
};// 示例用法
int main() {std::vector<int> data = {5, 3, 8, 6, 2};Sorter sorter(new BubbleSort());sorter.sort(data); // 使用冒泡排序sorter.setStrategy(new QuickSort());sorter.sort(data); // 使用快速排序return 0;
}

违背依赖倒置原则的点

  1. 直接依赖具体实现

    • Sorter 类持有一个指向 SortStrategy 的原始指针。这意味着 Sorter 需要知道具体的排序策略(如 BubbleSortQuickSort)的存在。
    • 这种直接依赖使得 Sorter 类在添加新策略时需要修改代码。

    示例代码

    class Sorter {
    private:SortStrategy* strategy; // 直接依赖具体实现public:Sorter(SortStrategy* strategy) : strategy(strategy) {}void setStrategy(SortStrategy* strategy) {this->strategy = strategy; // 需要知道具体的策略类型}void sort(std::vector<int>& arr) {strategy->sort(arr);}
    };// 使用时需要直接创建具体策略
    Sorter sorter(new BubbleSort()); // 直接依赖于 BubbleSort
    
  2. 策略的创建与管理

    • Sorter 类的构造函数和 setStrategy 方法都需要传入具体的 SortStrategy 实现。这使得 Sorter 对具体策略的实现有直接的依赖,而不是依赖于抽象。这违反了高层模块不应直接依赖于低层模块的原则。

    示例代码

    // 策略的创建与管理
    SortStrategy* strategy = new BubbleSort(); // 直接创建具体实现
    Sorter sorter(strategy); // Sorter 依赖于具体的 BubbleSort// 当需要更改策略时
    sorter.setStrategy(new QuickSort()); // 仍然需要知道具体的 QuickSort
    

改进建议

为了更好地遵循依赖倒置原则,可以引入工厂模式或依赖注入,通过 SortStrategyFactory 类来创建具体的策略对象,使得 Sorter 类不再直接依赖于具体的策略实现。

使用工厂模式的示例

通过引入工厂类,Sorter 不再直接依赖于具体的策略实现,而是依赖于工厂来获取策略。这种方式符合依赖倒置原则,使得 Sorter 更加灵活,能够在不修改其代码的前提下支持新的排序策略。

class Sorter {
private:SortStrategy* strategy;public:Sorter(SortStrategy* strategy) : strategy(strategy) {}void setStrategy(SortStrategy* strategy) {this->strategy = strategy;}void sort(std::vector<int>& arr) {strategy->sort(arr);}
};// 工厂类
class SortFactory {
public:static SortStrategy* createSortStrategy(const std::string& type) {if (type == "bubble") {return new BubbleSort();} else if (type == "quick") {return new QuickSort();}return nullptr; // 或抛出异常}
};// 示例用法
int main() {std::vector<int> data = {5, 3, 8, 6, 2};SortStrategy* strategy = SortFactory::createSortStrategy("bubble");Sorter sorter(strategy);sorter.sort(data); // 使用冒泡排序strategy = SortFactory::createSortStrategy("quick");sorter.setStrategy(strategy);sorter.sort(data); // 使用快速排序// 记得释放内存delete strategy;return 0;
}

实际应用场景

  • 依赖注入:可以通过构造函数注入、属性注入或方法注入等方式实现依赖注入(DI),从而降低模块之间的耦合度。
  • 服务定位器模式:在某些情况下,可以使用服务定位器来管理依赖关系,尽管这可能会引入一些全局状态。

结合其他设计原则

  • 接口隔离原则:DIP 与接口隔离原则(ISP)密切相关,二者都强调依赖于抽象而非具体实现。可以通过设计更小、更专一的接口来增强灵活性。
  • 单一职责原则:遵循单一职责原则(SRP)可以进一步减少类之间的耦合,使得每个类只关注自己的功能,从而更好地遵循 DIP。

可能的误区

  • 不应过度抽象:虽然遵循 DIP 是重要的,但过度抽象可能导致代码复杂性增加。在设计时,应平衡抽象与实现的复杂性。
  • 依赖注入的复杂性:引入依赖注入框架虽然可以减少耦合,但也可能增加系统的复杂性,特别是在小型项目中。

总结

依赖倒置原则是实现高内聚、低耦合的关键。通过依赖于抽象而非具体实现,可以提高系统的灵活性和可维护性。在实际应用中,应结合其他设计原则,合理使用依赖注入等技术,以达到最佳的设计效果。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com