NSFX手册的学习(8)

灰盒复用

对于终端用户而言,一个组件只能通过它的接口进行操作。然而,在一个程序的内部,一个组件并不是一个黑盒子,它或许会提供并不会为终端用户所使用的内部函数。因此,一个组件的内部函数能够被复用,这样的效率更高。这种复用被称之为灰盒复用。

如果组件下层的类是可见的话,这个组件就是灰盒、可复用的。对于灰盒复用而言,一个组件被它的类型复用,所以无需用NSFX_REGISTER_CLASS()宏对其定义一个CID。

比如,假设Nameable类的定义是可见的,我们就可以通过使用MemberAggObject类模板重复利用它。

// member-aggregation.h
#include "config.h"
#include "nameable/nameable.h"

class MemberAggregation :
    virtual public IObject
{
public:
    MemberAggregation(void);
    virtual ~MemberAggregation(void);

private:
    NSFX_INTERFACE_MAP_BEGIN(MemberAggregation)
        // The second argument MUST be the IObject* interface
        // exposed by the aggregated component.
        NSFX_INTERFACE_AGGREGATED_ENTRY(INameable, &nameable_)
    NSFX_INTERFACE_MAP_END()

private:
    // MemberAggObject implements the IObject interface of the Nameable class,
    // which supports aggregation.
    MemberAggObject<Nameable>  nameable_;
};

NSFX_REGISTER_CLASS(MemberAggregation,
                    "edu.uestc.nsfx.tutorial.MemberAggregation");
不同于黑盒聚合方式,基于灰盒聚合方式的成员变量并没有动态的分配聚合组件。相反,聚合组件作为控制器组件的成员变量被定义。而且,灰盒聚合允许对任何聚合组件公有函数的接入。
在控制器组件的构造器中,成员变量被初始化。如下:
// member-aggregation.cpp
#include "config.h"
#include "member-aggregation.h"

MemberAggregation::MemberAggregation(void) :
    // Specify the controller of the aggregation component.
    nameable_(/* controller = */this)
{
    // The implementation of IObject on the aggregate component depends upon
    // the implemenation of IObject on its controller.
    // However, IObject on this component has not been implemented yet.
    //
    // Thus, neither query interface, nor modify the reference counter of
    // the aggregated component in the contructor.

    // Use GetImpl() to access the aggregated component class.
    // Any public functions can be accessed.
    nameable_.GetImpl()->SetDefault();
}
nameable_组件作为一个成员变量通过具体化它的控制器而被初始化。与黑盒聚合很相似,IObject接口不能在构造期间被使用,因为接口上的方式还没有被完全生效。
为了使得灰盒得到复用,MemberAggObject<T>提供了一个公有函数GetImpl()。这个函数可以返回一个T*类型的指针。例如,nameable_.GetImpl()返回一个指针来打包Nameable这个组件,而它的公有函数SetDefault()就能够被调用了。

学习资源自:https://github.com/Fuzzier/nsfx/blob/tutorials/tutorials.md#objectt

猜你喜欢

转载自www.cnblogs.com/lx61/p/12189039.html
今日推荐