From: Nathan on
In the past if I needed to control creation, deletion and caching of
objects (specifically relating to objects mapped to database records)
I'd create an engine class that handled all of this.

Now moving forward I'm looking to implement factories to handle the
creation of objects and various strategies for caching but where I'm
having difficulty is dealing with deletion.

Bearing in mind that the objects relate to records in the database and
the deletion needs to not only destroy the object but delete the
record in the db as well how should I go about it?

I could implement a delete method on the objects which would enable me
to encapsulate the functionality for the deletion of the record in the
db but then the object has to be deleted, which leads me back to
implementing some sort of engine class to call the delete method and
then destroy the object.

What approaches do other people take?

From: Dmitry A. Kazakov on
On 22 Feb 2007 13:35:17 -0800, Nathan wrote:

> In the past if I needed to control creation, deletion and caching of
> objects (specifically relating to objects mapped to database records)
> I'd create an engine class that handled all of this.
>
> Now moving forward I'm looking to implement factories to handle the
> creation of objects and various strategies for caching but where I'm
> having difficulty is dealing with deletion.
>
> Bearing in mind that the objects relate to records in the database and
> the deletion needs to not only destroy the object but delete the
> record in the db as well how should I go about it?
>
> I could implement a delete method on the objects which would enable me
> to encapsulate the functionality for the deletion of the record in the
> db but then the object has to be deleted, which leads me back to
> implementing some sort of engine class to call the delete method and
> then destroy the object.
>
> What approaches do other people take?

Deletion of a reference object should not necessary mean deletion of what
it refers to. It is useful to consider the lifetimes of the things
involved. With the proxy objects it is better be:

|<----------------- target------------------>|
|<---- reference 1---->|
|<---- reference 2---->|
|<---- reference 3---->|

Making lifetimes not nested is obviously asking for trouble. I presume that
aliasing (multiple references to the same target) cannot be avoided.

From this point of view the Delete method applied to a reference cannot
mean an immediate destruction of the target. It is only a request to the
engine you have mentioned. The target will be destructed (or not) later.
Delete can be called upon reference object finalization.

Making Delete public is an important design decision as well. If it is
publicly accessible then either there should be invalid (disconnected from
the target) references and all other methods should be able to deal with
this. So Delete first requests deletion (witch does necessary happens
immediately), and then invalidates the reference. Alternatively, Delete
should mean call the real Delete called later, when the reference object
itself gets finalized. The first alternative may also have weak-references,
which get notified upon Delete and invalidate themselves.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: H. S. Lahman on
Responding to Nathan...

> In the past if I needed to control creation, deletion and caching of
> objects (specifically relating to objects mapped to database records)
> I'd create an engine class that handled all of this.

One class?!? B-) I'll be those suckers tended to be pretty big.

Outside of CRUD/USER processing, one usually solves the customer problem
first and then worries about persistence. To deal with persistence one
creates a subsystem that exists to convert the problem solution's data
needs into specific persistence mechanisms like SQL queries. One reason
for this separation is that the problem solution really doesn't care if
persistence is managed in flat file, and RDB, an OODB, or on clay
tablets. IOW, one does not want to distract the focus on the customer
problem with persistence details.

The interface to the subsystem is designed around the problem solution's
needs (e.g., "Store this pile of data values I call X so I can get it
later.") The job of the persistence access subsystem is to translate
such requests into the persistence paradigm de jour. So if the
persistence mechanisms are based on RDBs, then the access subsystem will
tend to have abstractions like Schema, Table, and Query rather than
Customer and Account. IOW, the only semantics the access subsystem and
the problem solution share is the interface message. Each has its own
unique interpretation of the identity X.

[Obviously when the interface is defined one needs to have a consistent
mapping between the solution objects and the persistence objects in
mind. In a pure message interface, {message ID, <data packet>}, each
side needs to interpret 'message ID' (in practice, usually an interface
method name) in terms of its own implementation. Thus on the solution
side the data packet values (in practice, usually interface method
arguments) will map into particular object attributes while on the RDB
side the data packet values map into particular table fields.

The actual mapping gets formalized in terms of an encode or decode of
the message on each side of the boundary. This the solution extracts
attribute values and encodes them as method arguments while the access
side decodes method arguments into an appropriate query dataset.]

> Now moving forward I'm looking to implement factories to handle the
> creation of objects and various strategies for caching but where I'm
> having difficulty is dealing with deletion.
>
> Bearing in mind that the objects relate to records in the database and
> the deletion needs to not only destroy the object but delete the
> record in the db as well how should I go about it?

One often uses factory objects for object deletion as well because that
is symmetrical with instantiation. That is, the main job in deletion is
ensuring referential integrity by getting rid of all the relevant
relationships that were instantiated by the factory when the object was
created.

Typically the persistence is handled by having the delete method send a
message to the persistence access subsystem (e.g., "I just deleted Z.").
The persistence access subsystem then maps Z into one or more table rows
(for an RDB) and issues the appropriate update query to the DBMS.


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl(a)pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info(a)pathfindermda.com for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH



From: Nathan on
One class?!! yes that would be one big sucker!

In terms of the engine class I'd normally create one for each assembly
\library etc e.g. customer functionality would have a customer engine.

Interesting what you say about the factory handling deletion, I'd
never heard of that.

I totally agree with you in relation to a sub-system handling the
interaction between the business objects and the data storage.

Thanks for the thoughts.

From: Nathan on
So would you advocate keeping the high level engine class as a
'controller' that can handle the deletion of the object regardless of
when the actual data was deleted?