Design Patterns Used in Qt and OpenCV

以下是一些在 Qt 和 OpenCV 中用到的设计模式。

Design pattern Description Example cases
Abstract Factory This can be used to create socalled factory classes that are capable of creating objects and control the creation of new objects in every possible way, such as preventing an object having more than a defined number instance. The create() function in the DescriptorMatcher abstract class is an example of this design pattern in OpenCV.
Command Using this design pattern, actions can be represented with objects. This allows capabilities such as organizing the order of actions, logging them, reverting them, and so on. QAction: This class allows creating specific actions and assigning them to widgets.
For example, a QAction class can be used to create an Open File action with an icon and text, and then it can be assigned to the main menu item and a keyboard shortcut (like Ctrl + O) and so on.
Composite This is used to create objects that consist of child objects. This is especially useful when making complex objects that can consist of many simpler objects. QObject: This is the base of all Qt classes.
QWidget: This is the base of all Qt widgets.
Any Qt class with a tree-like design architecture is an example of the Composite pattern.
Facade (or Façade) This can be used to encapsulate lower-level capabilities of an operating system (or any system for that matter) by providing a simpler interface. Wrapper and Adaptor design patterns are considered to be quite similar in definition. QFile: These can be used to read/write files.
Basically, all Qt classes that are wrappers around low-level APIs of operating systems are examples of the Façade design pattern.
Flyweight (or Bridge or Private Implementation) The goal of this design pattern is to avoid data copying and use shared data between related objects (unless otherwise is needed). QString: This can be used to store and manipulate Unicode strings.
In fact, many Qt classes enjoy these design patterns that help to pass a pointer to a shared data space whenever a copy of an object is needed, which consequently leads to faster object copying and less memory space usage. Of course, with a more complex code.
Memento This can be used to save and (later on) load the state of objects. This design pattern would be the equivalent of writing a class that is capable of storing all properties of a Qt object and restoring them to create a new one.
MetaObject (or Reflection) In this design pattern, a so-called metaobject is used to describe the details of the object for a more robust access to that object. QMetaObject: This simply contains meta-information about Qt classes. Covering the details of Qt’s metaobject system is out of the scope of this book, but simply put, each Qt program is first compiled with the Qt MetaObject compiler (MOC) to generate the required meta objects and then compiled by the actual C++ compiler.
Monostate This allows multiple instances of the same class to behave the same way. (Usually, by accessing the same data or executing the same functions.) QSettings: This is used to provide application settings save/load.
We already used the QSettings class in Chapter 2, Creating Our First Qt and OpenCV Project, to load and save with two different instances of the same class.
MVC (Model-view-controller) This is a widely-used design pattern, and it is used to separate the implementation of the application or data storage mechanism (Model) from the user interface or data representation (view) and the data manipulation (controller). QTreeView: This is a tree-like implementation of model-view.
QFileSystemModel: This is used to get a data model based on the contents of the local file system.
A combination of QFileSystemModel (or any other QAbstractItemModel, for that matter) with QTreeView (or any other QAbstractItemView) can result in an MVC design pattern implementation.
Observer (or Publish/Subscribe) This design pattern is used to make objects that can listen (or observe) to changes in other objects and respond accordingly. QEvent: This is the base of all Qt’s event classes.
Think of QEvent (and all of its numerous subclasses) as a low-level implementation of the observer design pattern. On the other hand, Qt supports signal and slot mechanism, which is a more convenient and high-level method of using the Observer design pattern.
We already used QCloseEvent (asubclass of QEvent) in Chapter 2, Creating Our First Qt and OpenCV Project.
Serializer This pattern is used when creating classes (or objects) that can be used to read or write other objects. QTextStream: This can be used to read and write text into files or other IO devices.
QDataStream: This can be used to read or write binary data from IO devices and files.
Singleton This can be used to restrict a class to only a single instance. QApplication: This can be used to handle a Qt widgets application in various ways.
To be precise, the instance() function in QApplication (or the global qApp pointer) is an example of the Singleton design pattern.
The cv::theRNG() function in OpenCV (used to get the default Random Number Generator (RNG)) is an example of Singleton implementation. Note that the RNG class itself is not a Singleton.

本文节选自 Computer Vision with OpenCV 3 and Qt5