网页设计建设网站模板,php网站制作报价,wordpress2012主题二次开发,如何制作视频【设计模式】如何用C实现依赖倒置
一、什么是依赖倒置#xff1f;
依赖倒置原则#xff08;Dependency Inversion Principle#xff0c;DIP#xff09;是SOLID面向对象设计原则中的一项。它的核心思想是#xff1a;
高层模块不应该依赖于低层模块#xff0c;两者都应该…【设计模式】如何用C实现依赖倒置
一、什么是依赖倒置
依赖倒置原则Dependency Inversion PrincipleDIP是SOLID面向对象设计原则中的一项。它的核心思想是
高层模块不应该依赖于低层模块两者都应该依赖于抽象。抽象不应该依赖于细节细节应该依赖于抽象。
这个原则的目的在于减少代码耦合性使代码更具灵活性和扩展性。按照依赖倒置原则我们让上层的逻辑不直接依赖底层实现而是通过抽象接口或抽象类来控制两者之间的关系。
二、为什么使用依赖倒置
在没有依赖倒置的设计中高层模块如业务逻辑往往会直接依赖于低层模块如数据访问、服务调用。这种依赖会使得高层模块无法独立更改一旦低层模块发生变动所有依赖它的高层模块都需要跟着修改导致代码维护难度和出错率增加。
通过依赖倒置可以实现以下特性
更易于扩展可以随时替换低层模块的实现而不需要改动高层模块。增强测试性可以方便地替换低层模块便于Mock或打桩提升了代码的可测试性。提高灵活性可以根据需求切换不同的实现方便扩展和维护。
三、实现步骤 定义抽象接口基类定义一个抽象类Service.h实现了一个Test纯虚函数此抽象类不实现任何具体逻辑仅对外提供接口 Service.h #ifndef DIP_SERVICE
#define DIP_SERVICEnamespace DIP
{class Service{public:virtual ~Service() default;virtual void Test() 0;};
}#endif实现接口的具体类定义一个实现类ServiceImpl实现构造、析构、Test等函数逻辑。 ServiceImpl.h #ifndef DIP_SERVICEIMPL
#define DIP_SERVICEIMPL
#include Service.hnamespace DIP
{class ServiceImpl : public Service{public:ServiceImpl(int a);~ServiceImpl() override;void Test() override;private:int m_a;};
}#endifServiceImpl.cpp #include ServiceImpl.h
#include iostreamusing namespace DIP;ServiceImpl::ServiceImpl(int a) : m_a(a)
{std::cout In ServiceImpl, m_a m_a . std::endl;
}ServiceImpl::~ServiceImpl()
{std::cout In ~ServiceImpl, m_a m_a . std::endl;
}void ServiceImpl::Test()
{m_a;std::cout In Test, m_a m_a . std::endl;
}注入依赖通过构造函数依赖注入将实现DIP::Service接口的对象传入将具体实现传递给高层模块的接口指针或引用从而对具体实现DIP::ServiceImpl解耦。 main.cpp #include ServiceImpl.h
#include Service.h
#include memoryint main()
{int a 3;std::shared_ptrDIP::Service serviceImpl std::make_sharedDIP::ServiceImpl(a);serviceImpl-Test();
}在这种设计中高层的main函数依赖于抽象接口Service而不是具体的实现类。这样只要继承了Service接口的实现类都可以被使用。这就是依赖倒置带来的灵活性和扩展性。
四、完整实现 在以上三点的基础上继续编写CMakeLists.txt文件。 # 设置项目名称和最低CMake版本
cmake_minimum_required(VERSION 3.10)
set(ProjectName Service)
project(${ProjectName})set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)add_executable(${ProjectName} main.cpp ServiceImpl.cpp)此时代码结构如下。 命令行编译执行。 mkdir build
cd build
cmake ..
make -j12
./Service执行结果。 In ServiceImpl, m_a 3.
In Test, m_a 4.
In ~ServiceImpl, m_a 4.可以看到Service指针在不感知ServiceImpl具体实现的情况下仅通过调用接口实现了和ServiceImpl实例相同的功能。