Skip to content
jijinlong edited this page Nov 14, 2016 · 15 revisions

##C++依赖注入实现 我们的目标就是 能够影藏具体的实现,并且可以抽选相关的实现,使用时只约定接口即可。

   IAction action; // 定义的接口
   action.imp("ActionImp"); // 选择相关的实现,在配置文件中通过ActionImp 抽选相关的实现为action赋值
   action->doSometing(); //注意这里的-> 他是会调用的具体实现的方法

怎么能做到这点呢?我们一步步来,先实现基础的Interface类

template<typename T>
class Interface {
public:
	T * operator->() // 重载-> 调用子类相关函数
	{
		if (_buffer == 0) return 0;
		return static_cast<T*>((void*)_buffer);
	}
	Interface()
	{
		_buffer = 0;
	}
	virtual ~Interface()
	{
		if (_buffer) delete static_cast<T*>((void*)_buffer); // 注意并不是直接delete _buffer ,若是将无法调用实现的析构
		_buffer = 0;
	}
protected:
	void* _buffer; // 具体实现类 所使用 的空间
};

为什么不用 纯虚函数呢? 对象在使用时必须有实现,不然C++无法分配内存,所有必须是个包含空实现的虚函数来做,我们是需要在运行期指定实现的。我们定义IAction 来继承Interface 类,Interface类帮我们实现了->重载 可以让C++为我们自动调用实现类的方法。

class IAction:public Interface<IAction> {
public:
    virtual void doSometing(){}; // 空实现 必须是虚函数
    virtual ~IAction(){}; // 务必加上
    void imp(const char *name); // 指定使用实现的类
};

我们来定义一个实现

class ActionImp:public IAction {
public:
    void doSometing(){
        printf("dosometing"); // 就输出字符串
    }
};

我们怎么将 IAction 与 ActionImp 对应呢?简单的方式,为IAction 提供一个方法,在这个方法里 指定具体的实现

void IAction::imp(const char *name)
{
     if (name == "ActionImp")
     {
         _buffer = new ActionImp(); // 根据字符串来产生不同的实现
     }
}

这也是一种方法,很LOW,如果你觉得够用就这样用,但是我们希望代码少做这些 If Else 写一个基础的工厂来生产这些对象

void IAction::imp(const chr *name)
{
      _buffer = ObjectFactory::create(name); // 这样是不是更好? 
}

如何实现这样的ObjectFactory 呢?

Clone this wiki locally