Title: Designing a Persistence Framework with Patterns
1Chapter 37
- Designing a Persistence Framework with Patterns
2Persistent Objects
- Storage mechanisms
- Object databases
- Relational databases
- Other flat files, XML structures, hierarchical
databases, etc. - Object-Relational (O-R) mapping service maps an
object to a relational record.
3Persistence Frameworks
- Persistence framework general-purpose, reusable,
extendable set of types that provides
functionality to support persistent objects. - Persistence service subsystem created by
persistence framework. - In technical services layer.
- Called an O-R mapping service for RDBs.
- E.g., Hibernate for Java.
4Materialization
- Transforming a non-object representation of data
from a persistent store into objects. - Lazy materialization an instance is only
materialized on demand, when needed. - Implemented by a Virtual Proxy (sect. 37.18).
- Caching materialized objects are typically
cached for performance. - Dematerialization (passivation)
- The reverse transformation.
5Representing Objects as Tables
- Pattern define a table in an RDB for each
persistent object class. - Primitive object attributes map to columns.
- Attributes that refer to other complex objects is
more complicated.
6Fig. 37.1 Mapping objects and tables
7Object Identifier Pattern
- Assign an object identifier (OID) to each record
and object (or proxy of an object). - Relates records to objects.
- Avoids duplicates.
- Usually alphanumeric value.
- In object-land, represented by an OID interface
or class. - In RDB, usually a fixed-length char value.
- Every table has an OID as primary key.
- Maps every object to some row in some table.
8Fig. 37.3 OIDs link objects and records
9Accessing a Persistence Service with a Façade
- Façade provides a unified interface to a
subsystem. - Operation to retrieve an object given OID.
- Type of object to materialize is also needed.
- Operation to store an object (dematerialize).
- Façade delegates requests to subsystem objects.
10Fig. 37.4 The Persistence Façade
11Database Mapper Pattern
- Direct mapping persistent object class defines
the code to save itself in a DB. - Strong coupling to persistent storage.
- Reduced cohesion technical services mixed with
application logic. - Indirect mapping create a class that is
responsible for materialization,
dematerialization and object caching. - Database Mapper or Database Broker.
- Different mapper class for each persistent object
class.
12Fig. 37.5 Database Mappers
13Template Method Pattern (GoF)
- Define a method in a superclass that defines the
skeleton of an algorithm, with its varying and
unvarying parts. - Invokes other methods (hook methods), some of
which may be overridden in a subclass to provide
unique behavior at points of variability. - Template method is typically public, hook methods
protected.
14Fig. 37.6 Template Method pattern in GUI
framework
15Fig. 37.7 Template Method for mapper objects
16Fig. 37.8 Overriding the hook method
17Fig. 37.9 Template Method twice to factor common
code for RDB
18Persistence Framework for NextGen POS
- NextGen-specific classes are in a different
package from general technical services
Persistence package. - IMapper, AbstractPersistenceMapper, and
AbstractRDBMapper are part of framework. - ProductDescriptionRDBMapper is a subclass added
by application programmer. - ProductDescriptionInMemoryTestDataMapper produces
hard-coded objects for testing without accessing
an external DB.
19Fig. 37.10 The persistence framework
20Guarded Methods
- AbstractPersistenceMapper.get method contains
critical section. - The same object could be materializing
concurrently on different threads. - Entire persistence subsystem may be distributed
to a separate process on another computer. - PersistenceFacade as a remote server object.
- Many threads running simultaneously, serving
multiple clients.
21Fig. 37.11 Guarded methods in the UML
22Configuring Mappers with a Mapper Factory
- A factory object MapperFactory can be used to
configure the persistence façade with a set of
IMapper objects. - Dont name each mapper with a different
operation, as in - class MapperFactory
-
- public IMapper getProductDescriptionMapper()
- public IMapper getSaleMapper()
-
- Instead, return a collection of mappers
- class MapperFactory
- public Map getAllMappers()
23Data-driven Mapper Instantiation
- The façade can then initialize its collection of
IMappers with - class PersistenceFacade
-
- private java.util.Map mappers
- MapperFactory.getInstance().getAllMappers()
-
- The factory can read system properties or use the
reflective capabilities of the language (e.g.,
Java) to discover which IMapper classes to
instantiate.
24Cache Management
- Pattern Make the Database Mappers responsible
for maintaining a local cache of materialized
objects to improve performance. - When objects are materialized, they are cached,
with their OID as key. - Subsequent requests to the mapper for an object
will be satisfied from the cache if the object
has already been materialized.
25A Class for SQL Statements
- Consolidate all SQL operations in a Pure
Fabrication singleton. - SQL operations SELECT, INSERT, . . .
- RDB mapper classes collaborate with
SQL-statements class to obtain a DB record or
ResultSet (Java). - This is preferable to hard-coding SQL statements
into the different RDB mapper classes.
26Example of a SQL-statements Class
- Interface
- class RDBOperations
-
- public ResultSet getProductDescriptionData(OID
oid) - Public ResultSet getSaleData( OID oid )
-
- Mapper
- class ProductDescriptionRDBMapper
- extends AbstractPersistenceMapper
- protected Object getObjectFromStorage( OID oid
) - ResultSet rs RDBOperations.getInstance().
- getProductDescriptionData(o
id) - ProductDescription ps new
ProductDescription() - ps.setPrice( rs.getDouble( PRICE ) )
- ps.setOID( oid )
- return ps
-
27Transactional States and the State Pattern
- Assume
- Persistent objects can be inserted, deleted, or
modified. - Modifying a persistent object does not cause an
immediate DB update an explicit commit
operation must be performed. - The response of an operation depends on the
transactional state of the object - An old dirty object was modified after
retrieval. - An old clean object need not be updated in DB.
- Delete or save causes state change, not commit.
28Fig. 37.12 Statechart for PersistentObject
29Fig. 37.13 Persistent object classes extend
PersistentObject
- PersistentObject provides common technical
services for persistence
30The State Pattern (GoF)
- Problem An objects behavior is dependent on
its state, and its methods contain case logic
reflecting conditional state-dependent actions. - Solution Create state classes for each state,
implementing a common interface. Delegate
state-depended operations from the context object
to its current state obj. - Ensure the context object always points to a
state object reflecting its current state.
31Fig. 37.14 Applying the State pattern
32Database Transactions
- Transaction a unit of work whose tasks must
all complete successfully or none must be
completed. - Completion is atomic.
- Represent the set of tasks to be done with a
Transaction class. - The order of database tasks within a transaction
can affect its success and performance. - Ordering database tasks can help generally,
inserts first, then updates, then deletes.
33The Command Pattern (GoF)
- Problem How to handle requests or tasks that
need functions such as prioritizing, queueing,
delaying, logging, or undoing. - Solution Make each task a class that implements
a common interface. - Actions become objects that can be sorted,
logged, queued, etc. - Each has a polymorphic execute method.
- E.g., command objects can be kept in a history
stack to enable undo.
34Fig. 37.15 Commands for database operations
35Lazy Materialization with a Virtual Proxy
- Virtual Proxy (GoF) a proxy for another object
(the real subject) that materializes the real
subject when it is first referenced. - A lightweight object that stands for the real
object that may or may not be materialized. - E.g., a Manufacturer object is rarely used, but a
ProductDescription has attribute visibility to an
IManufacturer instance. - When ProductDescription sends a getAddress
message to the ManufacturerProxy, it materializes
the real Manufacturer, using its OID.
36Fig. 37.16 Manufacturer Virtual Proxy
37Representing Relationships in Tables
- Representing Object Relationships as Tables
pattern - One-to-one associations
- Place an OID foreign key in one or both tables
representing the objects in a relationship, or
treat as a one-to-many association, as below. - One-to-many associations (a collection) or
many-to-many associations - Create an associative table that records the OIDs
of each object in relationship.