integrated computer solutions incorporated presents design patterns in qt4 alan ezust april 2008
TRANSCRIPT
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 example
class 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 informationplease visit us atplease visit us at
www.ics.comwww.ics.com