Integrated ComputerSolutions Incorporated
presents
Design Patterns in Qt4
• Alan Ezust• April 2008
www.ics.com2
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Agenda• What are design patterns for?
– Qt uses at least 20!• What are anti-patterns?• Examples:
– Factory Pattern in plugins– Command pattern– Flyweight pattern
www.ics.com3
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
What is a Design Pattern?• It is a named rule or convention
– Solves a specific software design problem• What kinds of problems?
– those that lead to unmaintainable or inflexible code
– Affectionately called: anti-patterns• Gang of Four (Gamma, Helm, Johnson,
Vlissides):– "Design Patterns are descriptions of
communicating objects and classes that are customized to solve a general design problem in a particular context."
www.ics.com4
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
3 Kinds of Design Patterns• Structural
– how to organize objects• Behavioral
– how to organize code• Creational
– how to organize code that creates objects
www.ics.com5
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
What is an Anti-Pattern?– Copy and paste code– Reinventing the (square) wheel
• reimplementing a function/class that already exists in your framework
– Interface bloat• too many methods in a class• too many arguments in a function
– Hard coding• embedding assumptions about the environment
– God Object• Too many dependencies on a single object that “does
everything”
www.ics.com6
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Structural Patterns: Composite
• Composite Pattern– Object trees – Parent - Child relationships– What Qt classes implement this?
• [QObject, QWidget, QGraphicsItem, QTreeWidgetItem, QDomNode, QHelpContentItem, QResource]
www.ics.com7
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Composite Pattern UML
www.ics.com8
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
QObject: Composite and Component
www.ics.com9
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Decorator Pattern• Decorator Pattern (aka Wrapper)
– Attach additional responsibilities to an object dynamically
– Instead of using inheritance, wrap around the object and delegate
• QScrollArea provides a decoration around its underlying widget, and scrollbars as necessary
• QTabWidget decorates itself around underlying widgets and allows user to select between them.
• Fits into the larger QLayout as the underlying widget would.
– Other instances of Decorator pattern?
www.ics.com10
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Problems Decorator Solves• Easier to add scrollability to other existing
classes (QGraphicsView)• Other ways to add “scrollable” to a
TextArea:– Multiple inheritance: ScrollableTextArea
derives from TextArea and ScrollComponent– Push scrollability up into one of the TextArea's
base classes, switched off except when necessary
– ScrollComponent wraps around TextArea and 'decorates' it.
www.ics.com11
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Structural Patterns• Facade (aka Adapter, and sometimes
Wrapper too) Pattern– Cover up that ugly pointer/array, or non-portable
C code– Qt classes?
• [QFile, QProcess, QThread, QWidget, QSqlDatabase, QString,etc]
• Reflection Pattern– The ability to inspect an object for information
about its members – Qt classes?
• [QMetaObject, QMetaProperty]
www.ics.com12
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Behavioral Patterns• Iterator Pattern
– type-independent class or mechanism for traversing a collection
– What Qt structures implement this? • [iterator, Iterator, and foreach loops]
• Visitor Pattern– class/structure that visits generic/polymorphic
nodes (in a collection) and provides a way to plug in a different visiting action
• QTreeWidgetItemIterator a type-restricted iterator, can be considered a Visitor
• QAbstractItemModel provides the visiting action to a QTreeView, which visits nodes.
www.ics.com13
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Creational Patterns• Singleton Pattern
– Only one instance can be created– Qt classes:
• [QApplication, QPluginLoader::staticInstances()]]
• Monostate Pattern– Each instance has the same value– Qt classes?
• [QSettings]
www.ics.com14
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Creational Patterns cont'd• Factory method
– force instances to be created via the method– Qt functions?
• [QFileIconProvider QDomDocument::createElement()]
• Abstract Factory Pattern– A class with a virtual Factory method that can
be overridden in derived classes– Used to eliminate dependencies between
libraries• [QImageIOPlugin, QItemEditorFactory, QAbstractExtensionFactory, etc ]
www.ics.com15
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Plugins and Creational Patterns
• Plugin architectures need to use Creational patterns in creative ways– applications must create instances of objects
that are defined in plugins– exact types are not known to the application
• Well designed interfaces are key:– they expose common features of plugin-
supplied classes• Plugins supply concrete factories
www.ics.com16
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Qt Plugins • Most Qt plugins implement two classes:
– The “Plugin class” contains a Factory method– The other class (created by the factory) does all the
'real work'• QImageIOPlugin is an Abstract Factory for QImageIOHandler objects
• To define your own image format plugin, you must extend both classes– reading and writing is done by the Handler
www.ics.com17
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Qt Image Plugins• Qt creates one
instance of each QImagePlugin (singleton)
• Plugin libs register 'plugin' class via the Q_EXPORT_PLUGIN2 macro
• When an image of type T needs to be loaded– each plugin is checked with its capabilities(T)
method– if a plugin is found that can handle the file format and
requested operation, its handler is created and used
www.ics.com18
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Behavioral Patterns• Observer Pattern
– publish-subscribe event model– Where in Qt can we find this?
• signals/slots• Mediator Pattern
– Promotes loose coupling between objects– Where in Qt?
• [QAbstractItemDelegate]
www.ics.com19
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Behavioral Patterns• Template Method pattern
– Define the skeleton of an algorithm in a template function
– Qt algorithms use template methods– Qt containers are template-based
www.ics.com20
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Behavioral Patterns• Memento Pattern
– Capture an object's state so it can be restored later
– In Qt? • [QDataStream, QMainWindow::saveState()]
• Command Pattern– Abstract an executable 'unit of work'– switch statement vs virtual method call– Transaction journaling, undo, rollback, etc– What Qt classes implement this?
• [QUndoCommand, QRunnable, QProcess, QAction, QThread, QtConcurrentRun]
www.ics.com21
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Command Pattern Example• Long running threads with Progress Bar• A uniform solution would be nice
www.ics.com22
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com23
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Command Pattern Exampleclass Command : public QObject { Q_OBJECT public: Command() : m_aborted(false) {} virtual void run() = 0; void setAborted(bool a); bool isAborted() {return m_aborted;} signals: void newRow(QString, QString); void newProgressValue(int); void newProgressRange(int, int); protected: volatile bool m_aborted; 1 };
www.ics.com24
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
void MainWindow::runInThread(Command* cmd) { if (!canStartWorkThread()) return; workThread = new WorkThread(cmd); connect (workThread,SIGNAL(finished()),
this, SLOT(stopWorking())); connect (cmd, SIGNAL(newRow(QString, QString)), &resultsModel, SLOT(addRow(QString,QString))); connect (cmd, SIGNAL(newProgressRange(int, int)), &progressBar, SLOT(setRange(int, int))); connect (cmd, SIGNAL(newProgressValue(int)), &progressBar, SLOT(setValue(int)));
resultsModel.clear(); stopButton.setEnabled(true); workThread->start();}
void MainWindow::tag() { runInThread(new TagCommand); } void MainWindow::import() { runInThread(new ImportCommand); }
www.ics.com25
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Behavioral Patterns• Strategy Pattern
– Make algorithms interchangable as virtual functions on objects
• QXmlReader uses the strategy pattern– plug in a QXmlContentHandler for handling parse events
in different ways• QWidget::render()
– different render technique for each kind of widget– Similar to the command pattern
• use virtual method call instead of big switch statement
– Qt Classes? • [QtAlgorithms, QSqlDriverPlugin]
www.ics.com26
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Behavioral/Structural• Interpreter Pattern
– A 'word' (a function, or operator) in the language is a class in the application
• Instances of these 'words' each have an evaluate method (similar to command pattern).
• Can be joined together with “AND”, “OR”, or constraint objects to form more complex expressions
– This pattern is used to implement an interpreter for a language
• [QRegExp, QScriptEngine]
www.ics.com27
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Structural Patterns• Bridge
– Decouple abstraction from implementation• so they can vary independently
– Many Qt classes have a public API class and a corresponding private 'impl' class. This helps Trolltech:
• achieve platform independence• achieve sharing, and lazy copy on write• make major changes to implementation without
breaking binary compatibility with linked applications• implement the next two design patterns
www.ics.com28
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Bridge - Wrapper
(unpublished class)
www.ics.com29
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Structural Patterns• Proxy Pattern
– Provide a surrogate or placeholder for another object to control access to it
• Flyweight Pattern– Use lightweight objects as wrappers which
point to shared actual values• Qt Classes?
– [QString, QList, QMap, QDomNode, implicitly shared classes]
www.ics.com30
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Flyweight exampleclass MyString { public: MyString() : m_Impl(new MyStringPrivate) {} MyString(const char* p) : m_Impl(new MyStringPrivate(p)) {} MyString(const MyString& str); ~MyString(); void operator=(const MyString& str); void display() const ; int length() const; operator const char*() const; private: MyStringPrivate* m_Impl;};
www.ics.com31
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Flyweight Example cont'dvoid MyString::operator=(const MyString& str) { if (str.m_Impl != m_Impl) { if (--m_Impl -> m_RefCount == 0) delete m_Impl; m_Impl = str.m_Impl; ++(m_Impl->m_RefCount); }}MyString::MyString(const MyString& str) : m_Impl(str.m_Impl) { m_Impl -> m_RefCount++;}
MyString::~MyString() { if (--m_Impl -> m_RefCount == 0) delete m_Impl;}
www.ics.com32
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Summary• What are design patterns for?
– Help you avoid common pitfalls– What are anti-patterns?
• Qt4 uses at least 20 of them!– How many can you name? – Where are they used in Qt4?
• Why should I use them in my code?• Code examples
– Command pattern– Flyweight pattern
Integrated ComputerSolutions Incorporated
presents
www.ics.com34
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
Bibliography• [Ezust07] Introduction to Design Patterns in C++ and Qt4. Alan
Ezust and Paul Ezust. 2007, Prentice Hall. 0-13-187905-7.• [Fowler04] UML Distilled. Third Edition. Martin Fowler. 2004.
Addison Wesley. 0-321-19368-7 .• [Gamma95] Design Patterns. Elements of Reusable Object-
Oriented Software. Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. 1995. Addison-Wesley. 0-201-63361-2.
• [Thelin07] Foundations of Qt Development. Johan Thelin. 2007. Apress. 978-1-59059-831-3
• [Blanchette08] C++ GUI Programming with Qt 4, 2/E. Jasmin Blanchette and Mark Summerfield. 2008, Prentice Hall. 0-13-235416
Integrated ComputerSolutions Incorporated
presents
Thank you!Thank you!For more informationFor more information
please visit us atplease visit us atwww.ics.comwww.ics.com