Examples of C++ programming using policy policy patterns in design patterns

  • 2020-05-09 18:58:51
  • OfStack


When reading "C++ new thinking in design",     found that the strategic pattern (policy) was introduced at the beginning of 1. Strategic pattern does not belong to one of the classic design patterns, but is actually indispensable in our daily development. policy, strategy, policy, here means to split complex functional classes as far as possible into a combination of simple ones that are responsible for only one aspect of the behavior or structure. Increase the flexibility, reusability and extensibility of the library. policy is a virtual concept, which defines some interface specifications of a certain class of class. It does not correspond to the keyword of C++ grammar, but is an abstract concept.

Example 1:


//policy Common usage examples of patterns smartptr . 
template
<
  class T,
  template <class> class CheckingPolicy,
  template <class> class ThreadingModel
>
class SmartPtr
  : public CheckingPolicy<T>
  , public ThreadingModel<SmartPtr>
{  
  T* operator->()
  {
   typename ThreadingModel<SmartPtr>::Lock guard(*this);
   CheckingPolicy<T>::Check(pointee_);
   return pointee_;
  }
private:
  T* pointee_;
};

Example 2, for example, we define an policy, which is a template with the parameter T, which must have an Create function and return a pointer of type T. We can have different implementations of this definition to meet the different needs of different users.


template <class T>
struct OpNewCreator
{
  static T* Create()
  {
   return new T;
  }
};

template <class T>
struct MallocCreator
{
  static T* Create()
  {
   void* buf = std::malloc(sizeof(T));
   if (!buf) return 0;
   return new(buf) T;
  }
};

template <class T>
struct PrototypeCreator
{
  PrototypeCreator(T* pObj = 0)
   :pPrototype_(pObj)
  {}
  T* Create()
  {
   return pPrototype_ ? pPrototype_->Clone() : 0;
  }
  T* GetPrototype() { return pPrototype_; }
  void SetPrototype(T* pObj) { pPrototype_ = pObj; }
private:
  T* pPrototype_;
};

//test class
class Widget
{
};

// A method is called 1 : 
template <class CreationPolicy>
class WidgetManager : public CreationPolicy
{  
};
void main()
{

typedef WidgetManager< OpNewCreator<Widget> > MyWidgetMgr;


}

// A method is called 2 Because: 1 a Manager It's specific to something 1 Of the class class And so on Manager Specifies what to handle class Type. 
template <template <class Created> class CreationPolicy>
class WidgetManager : public CreationPolicy<Widget>
{  
};
void main()
{
  // Application code
typedef WidgetManager<OpNewCreator> MyWidgetMgr;
}

There are three different implementations of the above strategy to meet the needs of different customers.
But for the use of the above, we can have a better change: because of the realization of the Policy class1 will be inherited, so we want to consider his destructor, we make the destructor of 1 virtual, but it can affect the static compilation of template features, affect the efficiency, so we use protected or private destructor, does not affect the derived class to base class destructor, does not affect the use.
As amended below:


template <class T>
struct OpNewCreator
{
  static T* Create()
  {
  return new T;
  }
protected:
  ~OpNewCreator() {}
};

We can also modify manger above to achieve switch of creator policy:


template <template <class> class CreationPolicy>
class WidgetManager : public CreationPolicy<Widget>
{ 
  void SwitchPrototype(Widget* pNewPrototype)
  {
   CreationPolicy<Widget>& myPolicy = *this;
   delete myPolicy.GetPrototype();
   myPolicy.SetPrototype(pNewPrototype);
  }
};


The policy pattern plays an important role in the development of our reusable, extensible libraries, and is one of the basic building principles of OO.

Overall strategy pattern:
Advantages:
1. Use the policy pattern to avoid multiple conditional transition statements. Multiple transition statements are not easy to maintain.
2. The policy mode allows you to dynamically change the behavior of the object and dynamically modify the policy

Disadvantages:
1. The client must know all the policy classes and decide which one to use.
2. Too many classes -- the policy pattern creates many policy classes, and each specific policy class generates a new class. (this can be overcome by the overclass mode)


Related articles: