[11 使用C++11开发一个轻量级的IoC容器(工厂模式的应用及优化)] 11.1 IoC容器是什么

本文介绍了C++中的工厂模式,用于延迟产品对象的创建,以减少耦合性。然而,即使使用工厂模式,A对象仍间接依赖于Base对象。为了解决这个问题,文章探讨了控制反转(IoC)的概念,通过IoC容器配置依赖关系,进一步降低耦合。依赖注入作为IoC的一种形式,通过构造函数将依赖关系注入,实现对象间的彻底解耦。文章还提到了实现IoC容器需要解决的三个方面,并提供了一个IoC示例。
摘要由CSDN通过智能技术生成

工厂模式的定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。

类图如下:

第11章介绍了C++11改进工厂模式的各种优化手段,一层一层地解耦泛化封装。

先看一个由直接依赖产生耦合性的例子:

#include <iostream>
using namespace std;

struct Base
{
    virtual ~Base(){};
    virtual void Func(){};
};

struct DerivedB : Base
{
    void Func() override
    {
        cout << "call func in DerivedB" << endl;
    }
};

struct DerivedC : Base
{
    void Func() override
    {
        cout << "call func in DerivedC" << endl;
    }
};

struct DerivedD : Base
{
    void Func() override
    {
        cout << "call func in DerivedD" << endl;
    }
};

// 类似代理模式
class A
{
public:
    A(Base* interface) : m_inferfaceB(interface)
    {
    }

    ~A()
    {
        if (m_interfaceB != nullptr)
        {
            delete m_interfaceB;
            m_interfaceB = nullptr;
        }
    }

    void Func()
    {
        m_interfaceB->Func();
    }

private:
    // 依赖,是一种使用的关系
    // 虽然依赖相对于继承关系属于对象关系中最弱的一种,但也会产生耦合性
    Base* m_interfaceB;
};

int main()
{
    A* a = new A(new DerivedB());
    a->Func();

    delete a;
    return 0;
}

输出结果:
call func in DerivedB

A对象直接依赖于Base接口对象,会产生耦合性。看如下例子:

int main()
{
    A* a = nullptr;
    if (conditionB)
        a = new A(new DerivedB());
    else if (conditionC)
        a = new A(new DerivedC());
    else
        a = new A(new DerivedD());
    
    delete a;
    return 0;
}

耦合性产生的原因在于A对象的创建直接依赖于new外部对象,这属于硬编码,使二者紧耦合。一种解决方法是通过工厂模式来创建对象。

struct Factory
{
    static Base* Create(const string& condition)
    {
        if (condition == "B")
            return new DerivedB();
        else if (condition == "C")
            return new DerivedC();
        else if (condition == "D")
            return new DerivedD();
        else
            return nullptr;
    }
};

int main()
{
    string condition = "B";
    A *a = new A(Factory::Create(condition));
    a->Func();

    delete a;
    return 0;
}

工厂模式避免了直接依赖,降低了耦合性,但是A对象仍然要依赖于一个工厂,通过工厂间接依赖于Base对象,没有彻底解耦。

控制反转(Inversion of Control, IoC),就是应用本身不负责依赖对象的创建和维护,而交给一个外部容器来负责。这样控制权就由应用转移到了IoC容器,实现了控制反转。IoC用来降低对象之间直接依赖产生的耦合性。具体做法是在IoC容器中配置这种依赖关系,有IoC容器来管理对象的依赖关系。

void IocSample()
{
    // 通过IoC容器来配置A和Base对象的关系
    IocContainer ioc;
    // A与Base是依赖关系
    ioc.RegisterType<A, DerivedB>("B");
    ioc.RegisterType<A, DerivedC>("C");
    ioc.RegisterType<A, DerivedD>("D");

    // 由IoC容器区初始化A对象
    A* a = ioc.Resolve<A>("B");
    a->Func();

    delete a;
}

通过依赖注入(Dependency Injection, DI)来将对象创建的依赖关系注入到目标类型的构造函数中。如将上例中A依赖于DerivedB的依赖关系注入到A的构造函数中。这样,A对象的创建不再依赖于工厂和Base对象,彻底解耦。

实现IoC容器需要解决3个问题:

(1)创建所有类型的对象(11.2)

(2)类型擦除(11.3, 11.4)

(3)创建依赖对象(11.4)

参考网址:

http://c.biancheng.net/view/1348.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值