IOC机制,即反转控制。要理解这个词汇,需要先理解DIP原则。DIP原则,即软件设计的基本原则之一,依赖倒置原则。DIP原则强调代码设计,尽量依赖抽象层,而不是具体的实现。
所谓IOC,即让业务代码关心抽象,由IOC容器提供具体实现(例如oop对象实例),并且容器也要处理对象之间的依赖关系。如此一来,业务层代码彻底解耦,如同烤肉在高温下一般,开始产生让人愉悦的编程体验,这便是优雅。
以上就是这篇文章的背景。笔者最早接触IOC,是因为学习了Spring Boot框架。里面通过大量使用Java注解方式,实现对象实例的自动注入(Injection)和装配(Autowire),所以用cpp实现了一个类似原理的IOC库。
这篇文章不着重说明什么是IOC,而要说明IOC能带来什么好处。以属性源(Property Source)为例,我用IOC机制把属性源对象,自动注入到需要它的地方。
class IProperty /*接口*/
{
public:
virtual ~IProperty() = default;
virtual std::string get(std::string key) const = 0;
};
class Property : public IProperty /*实现*/
{
public:
std::string get(std::string key) const override
{
// Any property source applied here.
return "Hello, " + key;
}
};
以上代码,定义了属性源的接口,以及它的实现类。接下来看业务代码。
注入对象
class Application : public RESOURCE2(Property, IProperty, "myProps")
{
};
以上代码,通过 RESOURCE “注解” 向IOC容器注入了一个Property对象实例。
装配对象
class Service : public AUTOWIRE(IProperty)
{
public:
Service()
{
auto property= AUTOWIRE_DATA(IProperty);
auto value = property->get("myKey");
}
};
以上代码,通过 AUTOWIRE “注解” 把IOC容器中的Property对象实例,装配到业务类。这样就能访问属性源了。
总结
代码里面,Application类扮演属性的提供者,属性源可以来自配置文件,或者网络环境。这里无法避免和具体实现类关联。
而Service类扮演属性的使用者,代表业务场所。它仅仅关联 IProperty 抽象接口,而非具体的 Property 类,这样IOC就完成了业务和具体实现的解耦,同时也体现了DIP原则的精髓。
文章结束,感谢阅读。
具体代码请参考:https://github.com/ChivenZhang/iocpp