Академический Документы
Профессиональный Документы
Культура Документы
with Patterns
Persistent Objects
Storage mechanisms:
Object databases
Relational databases
Other flat files, XML structures, hierarchical
databases, etc.
Persistence 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.
Materialization
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
Dematerialization (passivation):
The reverse transformation.
Key Ideas
Key Ideas
Key Ideas
Mapping
Manufacturer
name
city
...
...
MANUFACTURER TABLE
: Manufacturer
name = Now&Zen
city = Mumbai
name
city
Now&Zen
Mumbai
Celestial
Shortening
San Ramon
Object Identifier
MANUFACTURER TABLE
Manufacturer
city
name
oid : OID
...
: Manufacturer
city = Mumbai
name = Now&Zen
oid = xyz123
OID
name
city
xyz123
Now&Zen
Mumbai
abc345
Celestial
Shortening
San Ramon
...
This is a simplified design.
In reality, the OID may be
placed in a Proxy class.
primary key
: DBProductsAdapter
: PersistenceFacade
PersistenceFacade
...
getInstance() : PersistenceFacade
pd = get(...)
Database Mapper
1
PersistenceFacade
interface
IMapper
1
Class
getInstance() : PersistenceFacade
get( OID, Class ) : Object
put( OID, Object )
...
ProductSpecification
RDBMapper
get(OID) : Object
put( OID, Object )
...
ProductSpecification
FlatFileMapper
Manufacturer
RDBMapper
...
...
...
each mapper gets and puts objects in its own unique way,
depending on the kind of data store and format
interface
IMapper
get(OID) : Object
put( OID, Object )
...
// template method
public final Object get( OID oid )
{
obj := cachedObjects.get(oid);
if (obj == null )
{
// hook method
obj = getObjectFromStorage( oid );
cachedObjects.put( oid, obj );
}
return obj;
}
Abstract
PersistenceMapper
TEMPLATE
+ get( OID) : Object {leaf}
# getObjectFromStorage(OID) : Object {abstract}
...
HOOK
IMapper
Abstract
PersistenceMapper
}
return obj
}
ProductDescription
RDBMapper
# getObjectFromStorage(OID) : Object
Fig. 37.9 Template Method twice to factor common code for RDB
IMapper
Abstract
PersistenceMapper
Abstract
RDBMapper
tableName : String
ProductDescription
RDBMapper
+ constructor ProductDescriptionRDBMapper(tabName)
# getObjectFromRecord(OID, DBRecord) : Object
ProductDescription
FileWithXMLMapper
+ ProductDescriptionRDBMapper(tableName)
# getObjectFromRecord(OID, DBRecord) : Object
# getObjectFromStorage(OID) : Object
Sale
RDBMapper
ProductDescription
InMemoryTestDataMapper
...
# getObjectFromRecord(OID, DBRecord) : Object
# getObjectFromStorage(OID) : Object
Persistence
1
+ PersistenceFacade
getInstance() : PersistenceFacade
1
Class
Abstract
RDBMapper
+ AbstractRDBMapper(tableName)
# getObjectFromStorage(OID) : Object {leaf}
# getObjectFromRecord(OID, DBRecord) : Object
- getDBRecord(OID) : DBRecord
interface
IMapper
get(OID) : Object
put( OID, Object )
...
Abstract
PersistenceMapper
+ get( OID) : Object {leaf}
# getObjectFromStorage(OID) : Object
...
Cache
Cache 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.
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(oid);
ProductDescription ps = new ProductDescription();
ps.setPrice( rs.getDouble( PRICE ) );
ps.setOID( oid );
return ps;
}
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.
New
commit / insert
[ from DB]
OldClean
save
rollback / reload
commit / update
OldDirty
delete
Legend:
New--newly created; not in DB
Old--retrieved from DB
Clean--unmodified
Dirty--modified
delete
OldDelete
rollback / reload
Deleted
commit / delete
Domain
ProductDescription
...
Persistence
PersistentObject
oid : OID
timeStamp:
DateTime
commit()
delete()
rollback()
save()
...
{ state.rollback( this ) }
{ state.commit( this ) }
{ state.save( this ) }
PersistentObject
PObjectState
oid : OID
state : PObjectState
commit()
delete()
rollback()
save()
setState(PObjectState)
...
commit(obj : PersistentObject)
delete(obj : PersistentObject)
rollback(obj : PersistentObject)
save(obj : PersistentObject)
OldDirty
State
Product
Specification
// default no-op
// bodies for
// each method
OldClean
State
New
State
OldDelete
State
Sale
...
...
...
...
commit(...)
delete(...)
rollback(...)
delete(...)
save(...)
commit(...)
commit(...)
rollback(...)
{ // commit
PersistenceFacade.getInstance().update( obj )
obj.setState( OldCleanState.getInstance() ) }
{ // rollback
PersistenceFacade.getInstance().reload( obj )
obj.setState( OldCleanState.getInstance() ) }
{ // delete
obj.setState( OldDeleteState.getInstance() ) }
{ // save
obj.setState( OldDirtyState.getInstance() ) }
{ // commit
PersistenceFacade.getInstance().insert( obj )
obj.setState( OldCleanState.getInstance() ) }
{ // commit
PersistenceFacade.getInstance().delete( obj )
obj.setState( DeletedState.getInstance() ) }
Transaction Operations
Database 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.
Transaction
commands : List
commit()
addDelete(obj:PersistentObject)
addInsert( obj:PersistentObject)
addUpdate( obj:PersistentObject)
sort()
...
use SortStrategy objects to allow
different sort algorithms to order the
Commands
interface
ICommand
execute( )
undo()
DBCommand
PersistentObject
object : PersistentObject
{
commands.add( new DBUpdateCommand(obj) );
}
perhaps simply
object.commit()
but each Command can
perform its own unique
actions
1..*
DBUpdateCommand
execute()
execute() {abstract}
undo() {leaf}
DBInsertCommand
execute()
commit()
...
DBDeleteCommand
execute()
PersistentObject
oid
...
ProductSpecification
1
manufacturer : IManufacturer
...
getAddress()
...
getManufacturerAddress() : Address
{
return manufacturer.getAddress()
}
interface
IManufacturer
Manufacturer
Proxy
Manufacturer
realSubject : IManufacturer
- getRealSubject() : IManufacturer
+ getAddress()
...
{
if ( realSubject == null )
realSubject = PersistenceFacade.get(oid, Manufacturer.class);
return realSubject;
}
1
Proxy-for
realSubject
address
getAddress()
...
{
return getRealSubject().getAddress()
}
Architectural Analysis
Architectural Analysis
Architectural Analysis
Interlayer collaboration
(UI,DOMAIN,TECHNICAL SERVICE
layer)
Apply faade, observer and controller
pattern.
Package design
Package design