Serializer Pattern

Table of contents:

A serializer is an object that is responsible only for reading or writing objects. With QDataStream, it is already possible to serialize and deserialize all Qvariant -supported types, including QList, QMap, QVector, and others. For other file formats, or more complex object models, we isolate the reading/writing in separate reader and writer classes. These classes are examples of the Serializer pattern [Martin 98].

A serializer that reads and writes to files should handle all of the file and/or stream initialization and cleanup. A serializer could also be used to send objects over a network from one socket to another.[4] In that case it would be responsible for connecting and disconnecting to/from the appropriate socket.

[4] Sockets are addressable entities, used as endpoints for sending and receiving data between computers. Qt has an abstract base class named QAbstractSocket, which provides the interface for working with various kinds of sockets, and a concrete QTcpSocket class, which provides a TCP (Transmission Control Protocol) socket.

In Figure 10.3, we have a UML diagram for two serializer classes. Together, they can read and write ContactList objects.

Figure 10.3. The Serializer pattern

In C++, serializer classes can have overloaded input/output operators, similar to iostream or QTextStream, so that we can use them with a familiar interface. To read a file into the container, it should be as easy as this:

ContactList cl;
ContactListReader reader("somefile.txt");
reader >> cl;

And analogously, when it is time to output, the client code should look like this:

ContactListWriter writer("somefile.txt");
writer << cl;

We achieve this by defining the following insertion operators:

ContactListReader& operator>>(ContactListReader& reader,
 ContactList& cl);
ContactListWriter& operator<< (ContactListWriter& writer,
 const ContactList& cl);

Example 10.9 shows how to implement customized i/o operators.

Example 10.9. src/containers/contact/serializer.cpp

[ . . . . ]

ContactListReader& operator>>(ContactListReader& reader,
 ContactList& cl) {
 reader.read(cl);
 return reader;
}

ContactListWriter& operator<< (ContactListWriter& writer,
 const ContactList& cl) {
 writer.write(cl);
 return writer;
}

In Example 10.9, we defined global (non-member) operators. It would also be possible to write member function operators. The reason it is necessary to define non-member operators for iostream and QTextStream is because we cannot modify those classes to add member functions.

10.6.1. Benefits of the Serializer

By using the serializer, it will become much easier to change the file format, or the transport layer, with only small changes in client code. In addition, removing serialization code from the model makes the model simpler and easier to maintain.

Exercises: Serializer Pattern

1.

Revisiting the Contact List exercise from Section 4.3, complete the implementation of ContactListWriter and ContactListReader classes for the ContactList, following the Serializer pattern, so that you can read and write a ContactList to a file.

When each Contact is serialized, it should be written on a single line, in a tab-separated format (tabs separating each field in the record). Therefore, a serialized ContactList should have a sequence of lines, each line representing a Contact.

2.

Write a main program that supports, at minimum, the following command line arguments. Feel free to add others after these are working.

Contact List Test Driver usage
 contact [-i inputfile] [-c] [-o outputfile] [-p]
 -i read contact list from specified inputfile into ContactList
 -c generate 10 more random contacts and add to ContactList
 -o write ContactList list to specified output file
 -p print ContactList to standard output
 

If an invalid option is supplied, or if no options are supplied, it should print the above "Contact List Usage".


Sorted Map Example

Part I: Introduction to C++ and Qt 4

C++ Introduction

Classes

Introduction to Qt

Lists

Functions

Inheritance and Polymorphism

Part II: Higher-Level Programming

Libraries

Introduction to Design Patterns

QObject

Generics and Containers

Qt GUI Widgets

Concurrency

Validation and Regular Expressions

Parsing XML

Meta Objects, Properties, and Reflective Programming

More Design Patterns

Models and Views

Qt SQL Classes

Part III: C++ Language Reference

Types and Expressions

Scope and Storage Class

Statements and Control Structures

Memory Access

Chapter Summary

Inheritance in Detail

Miscellaneous Topics

Part IV: Programming Assignments

MP3 Jukebox Assignments

Part V: Appendices

MP3 Jukebox Assignments

Bibliography

MP3 Jukebox Assignments



An Introduction to Design Patterns in C++ with Qt 4
An Introduction to Design Patterns in C++ with Qt 4
ISBN: 0131879057
EAN: 2147483647
Year: 2004
Pages: 268

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net