Re: Factories and lazy objects

From: H. S. Lahman (h.lahman_at_verizon.net)
Date: 06/19/04


Date: Sat, 19 Jun 2004 15:09:07 GMT

Responding to Carroll...

> I read with great interest your warnings about controllers and the problems
> that they may bring to the table. And you have good points that I will "chew
> on". But I think that in this case, short of us getting together with a
> couple of shots of "Jager" and a wrestling mat (or a whiteboard, your
> choice), we may have to agree to disagree. Yet I agree with 99% of what you
> say. The 1%: This system, I think, NEEDS a central Dispatcher that
> manipulates other objects to achieve the end. I think you give my Dispatcher
> too little credit.

Perhaps. There are some problem domains that have entities whose
responsibilities _in the problem space_ are to coordinate the activities
of other entities. For example, it is kind of tough to implement OS
time slicing without some notion of an object that owns the rules and
policies for sequencing the individual threads.

Such entities tend to show up much more commonly in domains that are
computing domains. That's because computing system designers tend to
anthropomorphize the structure around such entities because it is a
convenient mapping. That then becomes a domain idiom. So when
implementing threading we always talk about ThreadManagers and when
implementing asynchronous infrastructures we always talk about
EventQueueManagers. That may not be good from an OO viewpoint, but much
of the computing space was defined long before OO techniques appeared on
the scene so one models the space as the domain expert perceives it.

Your problem domain seems to be a mix of pure customer domains (e.g.,
Account) and computing domains (e.g., DB persistence). So it is
possible that your problem is one of a general class of problems where
the computing side has a Dispatcher idiom that any domain expert for the
general class of problems would recognize. I'm just skeptical based on
the description so far because I always seek to avoid such abstractions
whenever possible.

>>What is MFC, exactly? It's beginning to sound like some surrogate for
>>another application that is interoperable with your application.
>
>
> Very perceptive. Yes, there is another system that the MainFrameConnection
> (MFC) actually talks to at production. Its called GTM (Global Transaction
> Manager; talk about self importance!). Its a system written by the "central
> office" that acts as a Facade to the actual mainframe data. It returns a
> String that contains the data that you requested. The MFC's job would be to
> get the String from GTM, parse it out, and push those values into Account.

OK, that is what I envisioned. Depending on the complexity of the
parsing and how well identity matches up across the boundary (i.e., how
well the problem solution view matches the DB view of the data), I might
consider putting that responsibility in a subsystem.

One should tailor the interface to persistence to suit the solution's
needs, not the DB data structures. For complex applications that may
mean the mapping of objects and tables or attributes and fields may not
be an exact fit. If so, one needs to encapsulate the conversion rules
so that the DB view can change without affecting the solution. OTOH, if
the mapping happens to be 1:1 and things aren't very complicated, a
simple class will do.

Note that for this semantics your MFC is acting as a Facade to
persistence at the application level. IOW, MFC is doing for your
application what GTM is doing for all applications.

> But there's more: not all Processes are ready to hit production data right
> off the bat. So one of the parameters passed to
> MainframeConnection.getAccount() is a parameter that tells MFC whether to
> pull the data from "real" production (the true jewel, actual people's
> financial data), "test" production (a mirror of a subset of the "real" data,
> but housed on the mainframe), and test local (a simple Access database that
> we have complete control over, but useful for unit testing and the like ).
> But again, I think, here I think that I'm solid. The Dipatcher only passes
> the "region" parameter from the Proc table.

I am uncomfortable with this. Essentially you have three different
access modes for persistence that you substitute based upon test vs.
production context. Whoever calls getAccount() must understand the
context of access in order to obtain Account information. That creates
a dependency in that client on the test context.

To avoid that dependency you might want to think along the lines of:

          * get info from 1
[Client] ------------------- [MFC]
                 R1 A
                                | R2
                   +------------+-------------+
                   | | |
              [Production] [MainTest] [LocalTest]

The R1 relationship can be instantiated to the proper subclass instance
by someone else who understands the context of the access. Then the
Client needs to know nothing about that context; it just does its thing
with Account information. It will also simplify MFC by isolating each
mode if there are significant differences in accessing Access vs GTM.

Alternatively, if the differences are trivial (e.g., just the server
path), you can provide a mode attribute in MFC and let that "someone
else" set the mode context instead of instantiating a subclass relationship.

Note that Dispatcher has to have a relationship to the right Proc table
in order to insert the region parameter in the massage. Somebody has to
define that relationship and they will understand the context. So they
would be the logical one to instantiates R1 or set a mode attribute in
MFC. That keep Dispatcher out of the loop.

>>>I have a feeling that eventually I will lose the MainFrameConnection
>
> object
>
>>>and make the Account object responsible for getting its data. At least
>
> then
>
>>>I can do something like:
>>>
>>>class Account{
>>> private List Comments;
>>>
>>> public List getComments(){
>>> if Comments = null {
>>> // tap Mainframe
>>> // populate Comments
>>> }
>>> return Comments;
>>> }
>>>}
>>>
>>>I can't think of a way to do that and still keep the MFC without
>
> populating
>
>>>List even though it may not be needed (by the Process). It would be
>
> (given
>
>>>my world) very wasteful to do so.
>>
>>Sorry, but I would need more words around this. The Comment list is a
>>new requirement. I was already guessing and any further speculation
>>here with more context would be hand-waving.
>
>
> Its the same as Transaction. A "1 to Many" where the contained object
> depends on the Account.
>
> Back to the original question. I can delegate accessing raw data and
> populating the Account all day long. But how to do it most effectively?
> Sure I could pull the ENTIRE Account object (with all its Transactions and
> Comments and Statements and SegPlanStoresand etc ad nauseum) and all its
> other properties and contained objects, but I would RATHER pull them only
> when necessary. That is, only when the Process needs them.

This opens another Pandora's Box. What's efficient for the application
may not be efficient for the DB. Another reason for making MFC a
subsystem is that one can deal with DB optimization there. While hardly
infallible, it is usually a good rule of thumb to minimize DB
transactions, especially if the join is "compiled" in the DB. The MFC
subsystem can then pull the entire Account "object" as a single dataset
that it buffers in a local cache. It can then parse that dataset on an
as-needed basis to resolve more limited solution requests. One can even
add exotic LRU algorithms to the subsystem to deal with the local
dataset cache when transactions are random and separated in time.

Obviously this depends a lot on the nature of the transactions accessing
Account-related information (e.g., a tendency for multiple transactions
against different Account information clumped together in time). But
there can be substantial performance benefits if one separates the DB
access problem from the customer problem.

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

H. S. Lahman
hsl@pathfindermda.com
Pathfinder Solutions -- Put MDA to Work
http://www.pathfindermda.com
(888)-OOA-PATH



Relevant Pages

  • Re: Factories and lazy objects
    ... >>But who connects Dispatcher to the right Proc table? ... they can notify MFC directly so that neither Proc ... > treats them all equally (as does the Account). ... > encapsulating all the instantiation rules and policies." ...
    (comp.object)
  • Re: Newbie question about db normalization theory: redundant keys OK?
    ... fan of persistent message queues. ... If your queue is ... Or if some of the queued transactions can be rolled ... geographically separated databases storing account balances. ...
    (comp.databases.theory)
  • RE: Carry forward balance of account
    ... your database contains hundreds of thousands of transactions. ... CurrentFiscalYear field in my Company table... ... Use the Income and Expense balances to calculate a net profit or loss ... Update the G/L AccumulatedProfitOrLoss account accordingly. ...
    (microsoft.public.access.modulesdaovba)
  • Re: G/F#
    ... There must be ways to account for this music within classical ... the CPP language and its applications, you would have seen that they ... cadence from bII to I in any form did not exist. ... They don't exist for the context you asked. ...
    (rec.music.theory)
  • RE: Display queried records with Null values (null recordcount)
    ... tables related to Assets and Transactions tables in the query, ... since AssetID from tblAssets is a foreign ... The query would return multiple rows per account, ...
    (microsoft.public.access.gettingstarted)