Design Pattern 4: Template Method Pattern

Source: Internet
Author: User

In the previous article, we compared the frameworks and design patterns. Generally, application frameworks use a lot of design patterns. The application development framework allows inheritance from one or more classes to create a new application and reuse almost all the code in the existing class, and overwrite one or more functions to customize the required applications.

A basic concept in the application development framework is the Template Method mode, which is so common that we don't even think it is a pattern when using it, it reaches the blind-eye level.

An important feature of the template method pattern is it (the template method here is not the pattern name, but the method or function we call the template method pattern) is defined in the base class (sometimes as a protected or private member function) and cannot be modified-the template method mode is "stick to the same code ". It calls other basic functions (that is, the functions covered by the derived classes) to complete their work, but the client programmer does not need to directly call these functions.

We will first provide a simple example, and then find some ready-made examples in some common application development frameworks for your reference.

class IUIElement {protected:    virtual void drawBackground(Painter * painter) = 0;    virtual void drawElement(Painter * painter) = 0;    virtual void drawForeground(Painter * painter) = 0;    public:    void draw(Painter * painter)    {        drawBackground(painter);        drawElement(painter);        drawForeground(painter);    }};class CButton : public IUIElement {protected:    void drawBackground(Painter * painter)    {        //draw background    }    void drawElement(Painter * painter)    {        //draw icon        //draw text    }    void drawForeground(Painter * painter)    {        //draw foreground if necessary    }};
The above code is very simple. We often implement similar classes in daily development. The draw () method of IUIElement is the template method, it calls drawBackground, drawElement, and drawForeground to complete element painting.

In some of the development frameworks I have used, there are many examples of template method patterns. Let's take a look at them.

Qt is an application framework fully implemented using C ++. It can be used on Windows, Linux, Android, iOS, Mac, Saipan, and other platforms. The QWidget class is the base class of all visible control classes in Qt. It uses the template method mode. When using such classes as QWidget, QLabel, and QListView, We can reload paintEvent and keyPressEvent, but there is no need to worry about where and when the methods we reload will be called, but they are actually called by template methods (such as render) in QWidget. The following are some of the methods that can be called by the QWidget template method (from Qt source code ):

protected:    // Event handlers    bool event(QEvent *);    virtual void mousePressEvent(QMouseEvent *);    virtual void mouseReleaseEvent(QMouseEvent *);    virtual void mouseDoubleClickEvent(QMouseEvent *);    virtual void mouseMoveEvent(QMouseEvent *);#ifndef QT_NO_WHEELEVENT    virtual void wheelEvent(QWheelEvent *);#endif    virtual void keyPressEvent(QKeyEvent *);    virtual void keyReleaseEvent(QKeyEvent *);    virtual void focusInEvent(QFocusEvent *);    virtual void focusOutEvent(QFocusEvent *);    virtual void enterEvent(QEvent *);    virtual void leaveEvent(QEvent *);    virtual void paintEvent(QPaintEvent *);


The first UI framework I came into contact with was MFC/ATL, followed by WTL. There are also a large number of template Mode Applications in MFC, which will not be described in detail. Here we will mention WTL, which also uses the template method mode, and is a very special implementation.

Developers who have used WTL know that this framework uses a large number of templates, which is far from being a non-template. Here is the special feature of using the template method mode in WTL. It introduces the template, reduces the frequency of use of inheritance (we know there is a problem called the "vulnerable base class" problem ). For example, the template class cmdiframeworkwimpl implements the OnSize method and associates it with the WM_SIZE message through the MESSAGE_HANDLER macro. In fact, the MESSAGE_HANDLER macro has introduced the template method, but we cannot see it, if you are interested, you can study the header file of MFC or the header file of ATL. In particular, let's take a look at the following code and analyze it later.

LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/){if(wParam != SIZE_MINIMIZED){T* pT = static_cast
 
  (this);pT->UpdateLayout();}// message must be handled, otherwise DefFrameProc would resize the client againreturn 0;}
 
The code above demonstrates not the template method itself, but the method that is overwritten by the derived class called by the template method. In OnSize, The static_cast is used to convert this pointer to the T pointer of the template class, And the UpdateLayout method of T is called to deal with the SIZE change. In this way, multiple document windows with different functions can be generated during compilation by inputting different T. We know that Strategy is to select an algorithm at runtime, while WTL combines the template method mode with the policy mode to achieve a wonderful effect: the policy is fixed during compilation (please understand the template usage), but we have a dynamic choice when writing code.

For more information, see application development on Android. View is the base class of all visible controls. If we want to implement a custom View, so onDraw, onMeasure, onLayout, onKeyDown and other methods may need to be overloaded. The template method mode is also working. You can view the source code of the Android application framework.


There is a basic problem in the template method mode, that is, the vulnerable base class. For example, after each release of the new version of MFC, you may need to adjust your program to adapt to it-although the compilation passes, however, the program behavior may become unexpected due to changes in the base class. We say that combination is superior to inheritance, and it is related to this issue. Java has interfaces, which can force derived classes to implement every method. C ++ does not have interfaces, but pure virtual functions can simulate interfaces. We should try to use interfaces and combinations as much as possible, instead of using inheritance without thinking about it ).

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.