Abstract Factory

 Object Factory用以生成一个对象,Abstract Factory用以生成多个关联的对象。

对于Abstract Factory而言,它有两个问题造成耦合度太高。一是Abstract Factory必须知道所有Abstruct Product,具体工厂必须知道它要生成的所有具体类。

Loki的AF解决了这个问题,在这里,我关心它如何做到的。

对于AF的抽象接口,Loki如此处理:

template     < class  T >
class     AFUnit
{
public:
    
virtual    T*    DoCreate(Type2Type<T>)    = 0;
    
virtual    ~AFUnit();
}
;

你可能需要生成好几个类,但这没有问题,GenScatterHierarchy可以把这个类应用于所有的TList成员类型。明显,不同的类有不同的DoCreate方法,为了获得正确的函数调用,这个Type2Type必不可少。

Loki使用了极具威力的TypeList传递待生成的类信息:

template
<
    
class     TList,
    template    
< class >      class     Unit     =  AFUnit
>
class     AbstractFactory    : public  GenscatterHierarchy < TList,Unit >
{
public:
    typedef    TList    ProductList;
    template    
<class T>
    T
*    Create()
    
{
        Unit
<T>&    unit    = *this;
        
return    unit.DoCreate(Type2Type<T>());
    }

}
;

好极了,GenscatterHierarchy可以把Unit应用于每个TList中的类型。对于特定的类型T,使用特定的Unit的Docreate方法生成。其实Create是一个分派器,对于特定的类型通过它你可以获得对应的产品。在这种情况下,你可以把AbstractFactory转型为某个具体类型工厂传递给特定的生成模块。

譬如T类型的文件只关心生成T,所以你可以传递AbstractFactory<T>,该文件所要做的只是实现T的DoCreate方法。

到此我们对这个框架有了大致的理解,但是还是没有说明如何实现DoCreate,其实解决方法比想像中的要简单。

template     < class  ConcreteProduct, class  Base >
class     OpNewFactoryUnit    : public     Base
{
    typedef    typename    Base::ProductList    BaseProductList;
protected:
    typedef    typename    BaseProductList::Tail    ProductList;
public:
    typedef    typename    BaseProductList::Head    AbstractProduct;
    ConcreteProduct
*    DoCreate(Type2Type<AbstractProduct>)
    
{
        
return    new    ConcreteProduct;
    }

}
;

如此所有产品都得到了DoCreate方法。但是有个问题,OpNewFactoryUnit的包含文件要知道所有的产品类。其实这不是问题,我们来看ConcretteFactory的实现再讨论这个问题:

template     < class  AbstractFact,
            template 
< class , class , >   class  Creator  =  OpNewFactoryUnit
            
class  TList  =  typename AbstractFact::ProductList
            
>
class  ConcreteFactory
    :
public     GenLinearHierarchy < typename TL::Reverse < TList > ::Result,Creator,AbstractFact >
{
public:
    typedef    typename    AbstractFact::ProductList    ProductList;
    typedef    TList        ConcreteProductList;
}
;

首先一个问题,OpNewFactoryUnit在定义的时候不需要知道任何类,因为它只是操作模板参数,而它的使用地方是在ConcreteFactory中,这个时候一个参数就是TList,TList肯定知道需要的一切类,这个需要的代价就是文件包含。当然,OpNewFactoryUnit没有任何多于文件依赖。

上面代码也展示了具体工厂的实现。ConcreteFactory(最终)继承于AbstractFactory,所以获取产品的方法不会有任何修改。所以这里无需定义太多东西。而ConcreteFactory最后的继承于一个施加于OpNewFactoryUnit的TList作用的AbstractFactory。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值