Transcript Slide 1

presents
Design Patterns in Qt4
• Alan Ezust
• April 2008
Integrated Computer
Solutions Incorporated
Agenda
• What are design patterns for?
– Qt uses at least 20!
• What are anti-patterns?
• Examples:
– Factory Pattern in plugins
– Command pattern
– Flyweight pattern
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
2
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."
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
3
3 Kinds of Design Patterns
• Structural
– how to organize objects
• Behavioral
– how to organize code
• Creational
– how to organize code that creates objects
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
4
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”
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
5
Structural Patterns: Composite
• Composite Pattern
– Object trees
– Parent - Child relationships
– What Qt classes implement this?
• [QObject, QWidget, QGraphicsItem, QTreeWidgetItem,
QDomNode, QHelpContentItem, QResource]
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
6
Composite Pattern UML
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
7
QObject: Composite and
Component
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
8
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?
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
9
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.
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
10
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]
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
11
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.
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
12
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]
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
13
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 ]
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
14
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
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
15
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
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
16
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
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
17
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]
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
18
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
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
19
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]
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
20
Command Pattern Example
• Long running threads with Progress Bar
• A uniform solution would be nice
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
21
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
22
Command Pattern Example
class 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
};
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
23
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); }
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
24
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]
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
25
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]
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
26
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
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
27
Bridge - Wrapper
(unpublished class)
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
28
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]
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
29
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;
};
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
30
Flyweight Example cont'd
void 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;
}
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
31
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
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
32
presents
Integrated Computer
Solutions Incorporated
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
©2008 Integrated Computer Solutions, Inc. All Rights Reserved.
www.ics.com
34
presents
Thank you!
For more information
please visit us at
www.ics.com
Integrated Computer
Solutions Incorporated