在前面一章的描述中说实话有点浅尝辄止,淡淡的扯了前面几节就黔驴技穷了,当然也不想再狗尾续貂了,所以很高兴开始了新的一章的征程 Object Factories。
说起这章,我们得先说说Factory模式, 这个模式的起源在于我们有太多的类似ConcreteClass* p = new ConcreteClass 的申明,而这些静态的申请在这里限定了p的类型, 我们的想法就是如果可以不显示把p的类型在这里显示出来,这时候一个factory在包装之后一个createInstance之类的轻便的接口可以帮助我们解决很多问题。这里援引了wikipedia上的一些说明:
The factory method pattern is an object-oriented design pattern. Like other creational patterns, it deals with the problem of creating objects (products) without specifying the exact class of object that will be created. The factory method design pattern handles this problem by defining a separate method for creating the objects, whose subclasses can then override to specify the derived type of product that will be created. More generally, the term factory method is often used to refer to any method whose main purpose is creation of objects.
但是像世界上没有完美的东西一样,createInstance带来的问题就是如果显示的指定你需要创建的实例具体类型。不开玩笑的是我确实曾经看到书中提到的形似不和谐的代码,这里是当初看到的UIFactory的代码片段。
- UIElement* createInstance(int elementID)
- {
- UIElement * p = NULL;
- switch(elementID)
- {
- case 1:
- p = new UILabel;
- break;
- case 2:
- p = new UITextField;
- break;
- case 3:
- p = new UIButton;
- break;
- /*
- even more, we needn't list here
- */
- default:
- break;
- }
- }
所以,书上也提供了一种比较常见的解决方案,那就是关联性的容器。(尽管这里给出一个STL::Map,但是实际上Loki也并没有采用Map而是使用了类似的AssocVector。)这里就可以动态的添加新的数据类型了,这里通过一个Register的接口传入typeid(这里的ID还不是RTTI中的那个ID,应该说这只是一种独特的表示,可以是一个string或者int,enum等等)和对应的create函数。这样就能把匹配类型的事情交给容器去做(而且这部分代码是肯定不会改变的)。
这里的描述都是概念性的,真正在应用的时候,Loki还是会把这个概念清晰的方案整的很恢弘。这部书中给出了一些代码片段值得我们一看
- template
- <
- class AbstractProduct,
- typename IdentifierType,
- typename ProductCreator,
- template<typename, class>
- class FactoryErrorPolicy
- >
- class Factory
- : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
- {
- bool Register(const IdentifierType& id, ProductCreator creator)
- {
- }
- bool Unregister(const IdentifierType& id)
- {
- }
- AbstractProduct* CreateObject(const IdentifierType& id)
- {
- }
- }
typedef SingletonHolder
<
Factory
<
Shape, std::string, Functor<Shape*>
>
>
ShapeFactory;
在这里首先把Factory放到了SingletonHolder里面了,然后原来的create()函数也被Functor取代了:)深刻的感觉到,在随着读书的深入,慢慢的作者已经慢慢地把理解推向了应用的新高度了。。。