Boost logo

Boost :

From: Borgerding, Mark A. (MarkAB_at_[hidden])
Date: 2000-03-06 11:50:48


The text below is copied and pasted from a post to comp.lang.c++.moderated.
It describes a persistence framework I made a couple of years ago. Perhaps
you could use it for ideas?

It has some similarities to the proposed persistence library:
        1) separates data from persistence media
        2) allows easy streamability, i.e. <<,>>
        3) uses overloads for different member types

It also has a couple of neat extras:
        1) allows other types of operations other than just save and load
(e.g. database updates,deletes). Without changing data objects!
        2) allows stream-oriented as well as record-oriented persistence
mechanisms.
        3) does not require separate load/save functions (a possible source
of maintenance headaches)
        4) handles polymorphism, and can be extended to handle pointers
through factory pattern.

BEGIN_QUOTE from
http://x42.deja.com/getdoc.xp?AN=577017164&CONTEXT=952360117.1170735127&hitn
um=0
 
[snip -- cut out part explaining with adapter pattern]

Separate the data from the method of persistence.
Each must belong into it's own class hierachy.
 
So the following hierarchies might exist in your project
 
(Base classes ) (Subclasses )
 
                  /---- car
PersistentData <------- employee record
                  \---- email message
 
 
                    /--- file
PersistenceMeans <-------- database
                    \--- socket
 
The base classes depend on each other, but NOT on any specific
subclass. The subclasses may have dependencies on the base classes, for the
abstract functionality the provide.
 
 
// the "means" subclass is used for implementing the storage // and
retrieval of the types of data that a class may have as member // both POD
and common objects should be implemented.
class PersistenceMeans
{
public:
  virtual void Link(std::string memberName,int & refData)= 0; virtual void
Link(std::string memberName,char & refData)= 0; // all POD types
  virtual void Link(std::string memberName,foo & refData)= 0; // some common
class types, e.g. std::string
 
  virtual void Link(std::string memberName,PersistentData & refData)= 0; //
for aggregation/containment of other persistent objects
 
// .. And whatever else you wanna put in.
 
// see enhancements section below for a more elegant method
// of type extensibility
};
 
// the "data" subclass is responsible for describing itself to the //
abstract interface of PersistenceMeans
class PersistentData
{
public:
  virtual void DescribeDataTo(PersistenceMeans & refPm) = 0; virtual void
std::string GetTypeName() = 0;
// also suggest some type of version info
};
 
This approach allows for an easily extensible framework where it is very
easy to make objects persistent.
Example:
  std::string foo::GetTypeName() {return "foo";}
 
  void foo::DescribeDataTo(PersistenceMeans & pm){
    Link("myFoo",m_foo);
    Link("myBar",m_bar);
    // ... one for each data members
  }
 
The object can thus be sent to/ and retrieved from any
PersistenceMeans that exists. Whether it be an ostream, a
relational database, or ???.
 
Some enhancements I have made to the above idea that make it
more powerful (but are omitted here for clarity):
- allow subclass-extensible typed Linking by adding a templated
  Link() in PersistenceMeans, that in turn calls a virtual (not pure)
function that takes a void * and a 'const type_info&' so that the subclass
can decide if it will support the data type or not
- use a factory framework to allow polymorphic creation of base * objects
- require the "data" subclass to supply a virtual clone() function. See
virtual constructors section in "More Effective C++" - use RTTI to provide a
default type name for data objects
- add virtual function(s) to PersistenceMeans to give data objects
information about the characteristics of the media type
  (e.g. IsSerial, IsRelational, IsBinary,etc.)
- wrap the persistence base classes and concrete "means" classes in a
single namespace
 
Let me know if you would like clarification on any of these topics.
 

--
Mark Borgerding
mborgerding at acm dot org

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk