BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Help with data-aware objects in Model and State

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OO design
View previous topic :: View next topic  
Author Message
Shawn Oster
Guest





PostPosted: Tue Dec 09, 2003 9:44 pm    Post subject: Help with data-aware objects in Model and State Reply with quote



I'm pulling my hair out, anyone care to help prevent further hair loss?

I have what I *think* is a fairly solid data-aware framework. It allows
registering of heterogeneous data sources (not TDataSources) to a central
data broker (TMyDataBroker). My model requires data from all types of
sources, a database, from the model itself, from the environment, etc.
Every data-aware object has a link to a TDataField which knows how to get
the needed data, regardless of type. So far so good, works like a charm and
is fast.

Now the big hiccup. I need two different views of this data. I need the
live view (which basically pulls it's data from the database) and a sample
or design view. The first idea that comes to mind is to simply add a
property to the TMyDataBroker, something like UseSampleData: boolean. The
problem is that my data-aware objects are only linked to the TDataField,
which is contained in a TDataFieldList, which is owned by a TDataProvider,
which is contained in a TDataProviderList, which is finally owned by the
TMyDataBroker. The TDataField would have to follow an Owner chain 4 levels
up to find out if it should return real data or sample data.

Any thoughts on how to determine what the current state is inside my model
so I know what data to retrieve? I've asked a similar question like this
before about drawing routines and the suggestion was to have two different
views, so in this case a TLiveDataBroker and a TSampleDataBroker. That
worked wonderfully for drawing (thanks everyone) but that doesn't work in
this case because each object has a link to a TDataField. The model is
linked directly to the data.

My design below...

// base class for a single data field. I have a few descendant classes that
// work with concrete types, such as a DateTime, another that triggers
// an event when GetValue is called
TDataField = class
protected
procedure GetName(): string; virtual;
procedure GetValue(): string; virtual;
public
property Name: string read GetName();
property Value: string read GetValue();
end;

// type-safe TObjectList that holds TDataFields
TDataFieldList = class;

// holds a category of TDataFields. One of the categories is 'SystemInfo'
// with the fields being 'DefaultPrinter', 'MachineName'. Another is
'ModelInfo'
// with such fields as 'DocumentTitle', etc. Yet another is
'DatabaseProvider' which
// has a connection to a TDataSet. For each TField in the TDataSet there is
a mirrored
// TDataField in the provider.
TDataProvider = class;
public
DataFieldList: TDataFieldList;
end;

// type-safe TObjectList that holds TDataProviders
TDataProviderList = class;

// holds all the TDataProviders. Each TDataProvider is registered with the
broker with
// a category name. This way I can display all the categories (almost like
different tables)
// and their contained TDataFields for selection.
TDataBroker = class;
public
DataProviderList: TDataProviderList;
end;

// Holds a reference to a TDataField. Acts as a link between a data-bound
object
// and a TDataField, vary similar to a TFieldDataLink in DBCtrls. Also used
to pull
// just a subset of the TDataField's data. Some data-bound objects only
want the
// first character, or the last 3, etc.
TDataReference = class;
public
DataField: TDataField;
Length: integer;
StartPos: integer;
function GetValue(): string;
end;

// any data bound object
TSomeObject = class
public
DataReference: TDataReference;
end;

Thanks!

Shawn Oster


Back to top
Eric Hill
Guest





PostPosted: Tue Dec 09, 2003 11:04 pm    Post subject: Re: Help with data-aware objects in Model and State Reply with quote



Quote:
Now the big hiccup. I need two different views of this data. I need the
live view (which basically pulls it's data from the database) and a
sample


Can you just use a "development" database (DBISAM/Nexus/etc) that provides
a TDataset collection for use by the model at design time?

Eric



Back to top
Marc Rohloff
Guest





PostPosted: Wed Dec 10, 2003 3:01 pm    Post subject: Re: Help with data-aware objects in Model and State Reply with quote



Shawn Oster wrote on Tue, 9 Dec 2003 14:44:45 -0700 ...
<3fd64249 (AT) newsgroups (DOT) borland.com>

Quote:
Now the big hiccup. I need two different views of this data. I need the
live view (which basically pulls it's data from the database) and a sample
or design view. The first idea that comes to mind is to simply add a
property to the TMyDataBroker, something like UseSampleData: boolean. The
problem is that my data-aware objects are only linked to the TDataField,
which is contained in a TDataFieldList, which is owned by a TDataProvider,
which is contained in a TDataProviderList, which is finally owned by the
TMyDataBroker. The TDataField would have to follow an Owner chain 4 levels
up to find out if it should return real data or sample data.

I don;t think that the UI should be aware (at least not at this level)
that it is in design view. Ideally you would just want the change to
occur at the dataprovider level (or maybe use different data providers
for design mode.

If you need to bubble information up to the field you should remeber
that it is always bad practice to use too many references (ie.dots) to
access information as it implies bad encapsulation.

ie: ThisField.FieldList.Provider.ProviderList.Broker.IsDesignMode
is bad.
TField should have a design mode property as should at least TProvider
and TBroker. This reduces the code to:

ThisField.IsDesignMode

Once you have encapsulated this way you can implement this anyway you
want. Initially you might choose to implement TField.IsDesignMode to
just return FieldList.provider.IsDesignMode which in turn returns
ProviderList.Broker.IsDesignMode.

If you later find that this is a performance bottle-neck you have
insulated yourself from the implementation. You can always change
Provider.IsDesignMode to return a private value and
DataBroker.IsDesignMode to notify all its providers that the design mode
has changed (which in turn can notify all its fields)

Marc Rohloff
marc rohloff at bigfoot dot com

Back to top
Shawn Oster
Guest





PostPosted: Fri Dec 12, 2003 10:42 pm    Post subject: Re: Help with data-aware objects in Model and State Reply with quote

"Marc Rohloff" <dont (AT) mailme (DOT) com> wrote

Quote:
Shawn Oster wrote on Tue, 9 Dec 2003 14:44:45 -0700 ...
[email]3fd64249 (AT) newsgroups (DOT) borland.com[/email]

Now the big hiccup. I need two different views of this data. I need
the
live view (which basically pulls it's data from the database) and a
sample
or design view. The first idea that comes to mind is to simply add a
property to the TMyDataBroker, something like UseSampleData: boolean.
The
problem is that my data-aware objects are only linked to the TDataField,
which is contained in a TDataFieldList, which is owned by a
TDataProvider,
which is contained in a TDataProviderList, which is finally owned by the
TMyDataBroker. The TDataField would have to follow an Owner chain 4
levels
up to find out if it should return real data or sample data.

I don;t think that the UI should be aware (at least not at this level)
that it is in design view. Ideally you would just want the change to
occur at the dataprovider level (or maybe use different data providers
for design mode.

I've gone ahead and done something similar to this. I just didn't like
dealing with wiring up all the Owner properties. I see the VCL doing that
quite a bit, an object 3or 4 levels down (up?) knowing about the root object
of the model. It bothers me but I can see they probably had a reason.

I now have a data provider source which I swap out. So my
TDatabaseDataProvider links to a generic TDataSet, in design time I use a
kbmMemTable (thanks for the suggestion Eric Hill!) and when I go live I swap
that out for the "real" data. The only thing I don't like is that there is
some internal mapping from database field names to the field names in my
TDatabaseDataProvider that I need to rewire each time I set the source but
that seems a much better resolution.

Thanks for the help.

Shawn



Back to top
Marc Rohloff
Guest





PostPosted: Mon Dec 15, 2003 12:49 pm    Post subject: Re: Help with data-aware objects in Model and State Reply with quote

Shawn Oster wrote on Fri, 12 Dec 2003 15:42:43 -0700 ...

Quote:
I now have a data provider source which I swap out. So my
TDatabaseDataProvider links to a generic TDataSet, in design time I use a
kbmMemTable (thanks for the suggestion Eric Hill!) and when I go live I swap
that out for the "real" data. The only thing I don't like is that there is
some internal mapping from database field names to the field names in my
TDatabaseDataProvider that I need to rewire each time I set the source but
that seems a much better resolution.

Yes. It's hard to get around the rewiring part. I suppose it wouldn't be
too hard to write a routine to go through all the controls on a form and
do it.

The Delphi Database way of doing it of course is not to link to a field
but to link to a database andf a string field name. THis has it's
advantages since you can repoint the datasource quite simply but I never
liked the fact that you wouldn't find out about bad field names until
runtime.

Marc

Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OO design All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.