comp.lang.ada
 help / color / mirror / Atom feed
From: Thomas Beale <thomas_beale@invest.amp.com.au>
Subject: Re: use eiffel to build a CAM library?
Date: 1998/01/22
Date: 1998-01-22T00:00:00+00:00	[thread overview]
Message-ID: <34C68DFA.136E@invest.amp.com.au> (raw)
In-Reply-To: shanemEn5Ju8.2z6@netcom.com


Shane Miller wrote:

> in the above example, if the list of big objects contains
> 100 entries and the user (after he obtains his "copy")
> only modifies 35 objects, then copy-on-write saved 65%
> of the maximum amount of work (eg. if you deep-copied every
> one of the 100 objects that would 100% work).  these issues
> are consisently *NOT* talked about in eiffel literature.
> 
> shane miller
> geferan systems

This is a good question. A solution is not completely obvious.
What I have done is:

- add mark_for_store and marked_for_store features to a class
  from which all storable business objects must inherit. Note
  that with ISE's EiffelStore, only the root object of a 
  logical "business" object has to do this inheritance, e.g.
  you might have PERSON, with all kinds of bits and pieces
  e.g. ADDRESS, PERSON_NAME, etc, etc. Only PERSON need inherit
  from the storable ancestor.

- when you call modifier routines, they have to set 
  mark_for_store to True. This sounds tedious, but in reality
  I have not found it a problem. Again this only relates to 
  business objects, not the bits and pieces.

As an overall approach, I have come up with the following,
for complex objects. 

0. It is essential to understand the  difference between a 
business (or "domain") object such as PERSON, VEHICLE, 
NET_NODE etc, and the actual network of instances which will 
make up any of these objects. When you are talking about 
storing "objects" you have to actually think about networks
of instances, right down to the LINKABLE instances making
up a LINKED_LIST.

1. I call a business or domain object a "composition" of
instances. A composition is the smallest unit that can be
read from or written to the database, since modifications
and reading require the whole logical object.

2. Complex business objects (investments, vehicles, SCADA
control systems) tend to be "parts explosions" of informational
business objects. E.g. VEHICLE might be a business object
containing ENGINE and GEAR_TRAIN, each of which is also a
business object. I use the word "aggregation" to mean
aggregation of business objects. A "sub-aggregation" is
a partial "tree" from an intermediate point down. This is
very useful where the aggregations are trees of software 
objects in a CM system for example; a sub-aggregation
could correspond to a component, a subsystem, a project etc.

3. Now you are in a position to attach sensible semantics
to the read and write of a) compositions, aggregations (of
compositions), and sub-aggregations. Semantics include
granularity of modification, locking, version control and
so on. A typical example would be to enforce locking of
entire sub-aggregations when a modification was requested.

4. Once these basics are in place, you can implement intelligent
storage schemes. For example, if a business object composition
is altered, write the whole thing. You can't do otherwise - 
think about what happens at the instance level if the contents 
of PERSON.addresses: LINKED_LIST[ADDRESS] changes. Mark-for_store
can be implemented on a per-composition basis. Now it can be
seen that if an object like INVESTMENT has a LIST of PORTFOLIO,
and both INVESTMENT and PORTFOLIO are programmed as business
objects, a write on INVESTMENT will traverse into all PORTFOLIO
objects, writing only those marked-for-store.

This type of approach gets out of mindlessly traversing 
entire networks of objects connected by reachability. You
rarely want to do that. Instead, you want to traverse 
business objects and aggregations, and stop when you hit
a new aggregation, and simply update association references
to it. The aggregation relationship (as described above)
is the relationship type which determines the scope of
traversals for writing and reading.

Another area of complexity is business object validity.
When is a PERSON valid; particularly, while constructing a
PERSON object from its parts, when is it ok to call it
valid? Simple Eiffel invariants for valdity don't work,
since many operations may be needed on an object before it
is fully built (e.g. if consturcting it from RDBMS records).
When the composition is viewed as the unit of construction,
compositions are also the place to put basic validity
functions, as well as a marker of some kind saying when
an object has been built for the first time, and it is now
sensible to call my_obj.is_valid.

Obviously there are many details to a scheme like this, but
these are the essentials.

One last note: how do you decide what is a business object and
what is not? Does an ADDRESS need to be a business object? My
answer is: only if its existence is meaningful on its own.
If you want a repository of ADDRESS objects, then yes; if 
ADDRESS will only ever mean anything when building PERSON 
objects, then no.


- thomas beale




  reply	other threads:[~1998-01-22  0:00 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-01-21  0:00 use eiffel to build a CAM library? Shane Miller
1998-01-22  0:00 ` Thomas Beale [this message]
1998-01-22  0:00 ` Paul Johnson
1998-01-24  0:00   ` Thomas G. McWilliams
1998-01-25  0:00     ` Rob Heyes
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox