Loki庫讀解5(完):AbstractFactory.h讀注 (轉)

amyz發表於2007-10-09
Loki庫讀解5(完):AbstractFactory.h讀注 (轉)[@more@]

這應該是本系列的最後一篇了吧。有這麼多註解後,其它程式碼在語法上應該不存在困難了。剩下的,就是大家來多多領會《Modern C++Desing》的思想,並運用了。

// Last update: June 20, 2001

#ifndef ABSTRACTFACTORY_INC_
#define ABSTRACTFACTORY_INC_

#include "Typelist.h"
#include "TypeManip.h"
#include "HierarchyGenerators.h"

#include

namespace Loki
{

////////////////////////////////////////////////////////////////////////////////
// class template AbstractFactoryUnit
// The building block of an Abstract Factory
////////////////////////////////////////////////////////////////////////////////
//WQ注:定義了一個廠介面,而其實現由自己完成,並作為abtractfactory的引數
  template
  class AbstractFactoryUnit
  {
  public:
  virtual T* DoCreate(Type2Type) = 0;//WQ注:由於型別間去耦合,請注意它在overriding時的微妙效果:GenScatterHierarchy的多個Unit間將構成overloading,並且有同
名掩蓋效應。
  virtual ~AbstractFactoryUnit() {}
  };

////////////////////////////////////////////////////////////////////////////////
// class template AbstractFactory
// Defines an Abstract Factory interface starting from a typelist
////////////////////////////////////////////////////////////////////////////////

  template
  <
  class TList,//此變數名起得不好,BCB用掉了。
  template class Unit = AbstractFactoryUnit//WQ注:注意這個,不是TupleUnit型別,無法自動轉換到T型別。
  >
  class AbstractFactory : public GenScatterHierarchyUnit>//WQ注:請參考GenScatterHierarchy的講解圖,這時要將DoCreate加上了。
  {
  public:
  typedef TList ProductList;
 
  template T*
Create()//WQ注:派生類同名函式掩蓋基類版本,這兒於是玩了個模板技巧。注意,掩蓋的是可見性而不阻止overriding。
//WQ注:這個函式時沒法型別推導的,只能Create()方式呼叫。
  {
  Unit& unit = *this; //WQ注:T應該為Tlist中的一員,否則會拋編譯異常
return unit.DoCreate(Type2Type());//WQ注:避免了型別上的各種轉換,確保實現了上面的註解。
//WQ注:這是Herb Sutter的"對話"系列中講的"公有非虛介面調私有虛實現",可去找來多多體會。
//WQ注:這兩句話結合後,可選的DoCreate方法只剩一個了,達到了呼叫最精確的廠方法來構造的效果。傳統方法中,我們需要為型別進行編號,用switch…case來選擇方法。

  }
  };
 
////////////////////////////////////////////////////////////////////////////////
// class template OpNewFactoryUnit
// Creates an by invoking the new operator
////////////////////////////////////////////////////////////////////////////////

  template //WQ注:ConcreteProduct的典型實現就在下面。
  class OpNewFactoryUnit : public Base//WQ注:一定要仔細參考它的繼承圖。
  {
  typedef typename Base::ProductList BaseProductList;
 
  protected:
  typedef typename BaseProductList::Tail ProductList;
 
//WQ注:這個typedef也是遞迴的!結束點為(即AbstractFact)。此root是遞減遞迴,OpNewFactoryUnit最外層時它只一個Tn,OpNewFactoryUnit最裡面時它是T1…Tn的TypeList。(注意,這個內/外層僅為示意,並非精確詞彙。)
  public:
  typedef typename BaseProductList::Head AbstractProduct;
  ConcreteProduct* DoCreate(Type2Type)
//WQ注:ConcreteProduct是遞增遞迴,最外層時是T1,最內層時是Tn,所以,如果它所用的TypeList反有下序的話,則最外層時是Tn,最內層時是T1,正好和AbstractProduct順序相同!
  {
  return new ConcreteProduct;
  }
  };

////////////////////////////////////////////////////////////////////////////////
// class template FactoryUnit
// Creates an object by cloning a prototype
// There is a difference between the implementation herein and the one described
//  in the book: GetPrototype and SetPrototype use the helper friend
//  functions DoGetPrototype and DoSetPrototype. The friend functions avoid
//  name hiding issues. Plus, GetPrototype takes a reference to pointer
//  instead of returning the pointer by value.
////////////////////////////////////////////////////////////////////////////////
//WQ注:同樣供GenLinearHierarchy的Unit使用,形成原型廠。只不過要求TypeList中的型別都必須提供Clone函式。
  template
  class PrototypeFactoryUnit : public Base
  {
  typedef typename Base::ProductList BaseProductList;
 
  protected:
  typedef typename BaseProductList::Tail ProductList;

  public:
  typedef typename BaseProductList::Head AbstractProduct;

  PrototypeFactoryUnit(AbstractProduct* p = 0)
  : pPrototype_(p)
  {}
 
  friend void DoGetPrototype(const PrototypeFactoryUnit& me,
  AbstractProduct*& pPrototype)
  { pPrototype = me.pPrototype_; }
 
//WQ注:抱歉啊,我沒查到這種語法,但根據相關原則,這種語法是可以成立的,推測如下:friend本身不兼具申明的功能。但有了它,將使得內聯的函式變成非類成員了!只是擔心它的可見性,而且估計它仍然是內聯的,不能隨便取其地址。
  friend void DoSetPrototype(PrototypeFactoryUnit& me,
  AbstractProduct* pObj)
  { me.pPrototype_ = pObj; }
 
  template
  void GetPrototype(AbstractProduct*& p)
  { return DoGetPrototype(*this, p); }
 
  template
  void SetPrototype(U* pObj)
  { DoSetPrototype(*this, pObj); }
 
  AbstractProduct* DoCreate(Type2Type)
  {
  assert(pPrototype_);
  return pPrototype_->Clone();
  }
 
  private:
  AbstractProduct* pPrototype_;
  };

////////////////////////////////////////////////////////////////////////////////
// class template ConcreteFactory
// Implements an AbstractFactory interface
////////////////////////////////////////////////////////////////////////////////

  template
  <
  class AbstractFact,
  template class Creator = OpNewFactoryUnit,
  class TList = typename AbstractFact::ProductList
  >
  class ConcreteFactory
  : public GenLinearHierarchy<
typename TL::Reverse::Result, Creator, AbstractFact>
//WQ注:它的反序原因在前面已經講了。
  {
  public:
  typedef typename AbstractFact::ProductList ProductList;
  typedef TList ConcreteProductList;
  };
//WQ注:總結一下:實現時,必須從AbstractFactory派生實際廠,並提供所有版本的DoCreate>()方法的實現;使用時,使用Create();的形式。
} // namespace Loki

////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////

#endif // ABSTRACTFACTORY_INC_


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-975302/,如需轉載,請註明出處,否則將追究法律責任。

相關文章