 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Kern Carboni Guest
|
Posted: Sat Feb 19, 2005 7:36 am Post subject: Help with BO design |
|
|
Kiaora;
I am new to Delphi (1+ year) and was lucky enough to find this newsgroup
which has proved invaluable for my foray in OO;
Our current Radiology system is an Informix 3, dos based system, which I
have inherited in my new role. I have dedicated my sanity
to providing a modern GUI system and wanted to start on a good footing by
having the good people of this NG provide some guidance.
My initial ramblings produced
TBusinessObject
| Quote: | _TPersistentBusinessObject
_TVisit
_TVisitReport
_TVisiReportLine
_TPatient
_TDoctor
|
TBusinesObjectCollection;
| Quote: | _TPatientCollection
_TVisitReportLineCollection
|
TBusinessObjectIterator;
I understand the following (hopefully);
Without an OPF the BusinessCollection must have a mechanism of populating
itself ie SQL query;
Is the BusinessCollection responsible for the creation of the contained
object ie. the TVisitReportLineCollection will iterate
though the returned SQL result set, creating and populating visitReportLine
objects and adding them to itself?
Thanks in advance
Kern Carboni
Fulford Radiology Services
New Zealand
|
|
| Back to top |
|
 |
Bob Dawson Guest
|
Posted: Sat Feb 19, 2005 8:30 am Post subject: Re: Help with BO design |
|
|
"Kern Carboni" wrote
| Quote: | My initial ramblings produced
TBusinessObjectIterator;
|
Your domain--won't comment except to say that iteration is a generic
facility, not something peculiar to BOs, so I'd go for a very generic
IIterable interface with an equally general (but extensible) TIterator
class.
| Quote: | Without an OPF the BusinessCollection must have a mechanism of
populating itself ie SQL query;
|
Two schools of thought--either do that, or else have an external service to
which you can pass the collection for population. Needn't be a ful
OPF--could be just a helper class.
| Quote: | Is the BusinessCollection responsible for the creation of the
contained object
|
Again, you can either do that or externalize the function in a helper class.
Might look something like this
class procedure TBOCollection_DataSet_Adapter.PopulateCollection(aDataset :
TDataset; aCollection: TBusinesObjectCollection);
begin
aDataset.First;
while not aDataset.EOF do
begin
aCollection.AddItem(aCollection.ContainedClass.CreateFromDataRow(aDataSet));
aDataset.Next;
end;
end;
Not production code obviously--just food for thought.
bobD
|
|
| Back to top |
|
 |
Kern Carboni Guest
|
Posted: Sat Feb 19, 2005 10:37 am Post subject: Re: Help with BO design |
|
|
Hi Bob
Thanks for response;
| Quote: |
aCollection.AddItem(aCollection.ContainedClass.CreateFromDataRow(aDataSet)); |
Would I be correct in assuming ContainedClass would be a property containing
class reference of the type being held in the collection?
Is it feasible to set this in a constructor?
Before posting I had read the post below and it has added to my confusion
regarding collections and item creation.
| Quote: | An Order is a composition in which the Order Lines do not have a life
outside of the Order; if you want to create an OrderLine, then you have to
ask the Order to create it; if you want to delete an Order Line then you
have to ask the Order to delete it.
|
How would I decipher this in light of your earlier response?
I currently have a VisitReport ---> VisitReportLineCollection - which would
qualify as a composition?
Apologies for the mundane questions.
Regards
Kern
|
|
| Back to top |
|
 |
Bob Dawson Guest
|
Posted: Sat Feb 19, 2005 7:47 pm Post subject: Re: Help with BO design |
|
|
"Kern Carboni" wrote
| Quote: |
Would I be correct in assuming ContainedClass would be a property
containing class reference of the type being held in the collection?
Is it feasible to set this in a constructor?
|
Yep. If you have a base TBusinessObject with an appropriate virtual
constructor, then
you'd define the collection constructor as
//given TBOClass = class of TBusinessObject;
constructor TBusinessObjectCollection.Create(aBOClass : TBOClass);
Now in your TPersistentBusinessObject class you can do
class function TPersistentBusinessObject.ProvideCollection :
TBusinessObjectCollection;
begin
Result := TBusinessObjectCollection.Create(self);
end;
| Quote: | ask the Order to create it; if you want to delete an Order Line
then you have to ask the Order to delete it.
|
That's would be normal approach.
| Quote: | How would I decipher this in light of your earlier response?
|
Not sure where you're seeing the disconnect--can you be a bit more specific?
In general, remember that there are often differences between the way things
appear to work and what's actually going on--especially once one starts to
separate out different architectural layers. For example, I might write a
line like
newOrderLine := TOrder.AddLine;
but that doesn't mean that internally TOrder actually knows how to do
this--it may be just passing off the details to a service class and
shielding the app programmer from the complexities underneath. An OPF can be
ducklike (smooth and graceful above, paddling like mad underneath).
| Quote: | Apologies for the mundane questions.
|
Not an issue. Some of the simplest questions have led to threads lasting
weeks. Like "Should a persistent object have a Save method?" Opinions
differ. :-)
bobD
|
|
| Back to top |
|
 |
Kern Carboni Guest
|
Posted: Sun Feb 20, 2005 12:31 am Post subject: Re: Help with BO design |
|
|
Hi Bob
I think I was missing the connection due to inexperience in knowing which
predefined methods should appear
in various objects in the application layers.
ie. a TBusinessObject would have an AddLine method to create a single
instance and add to collection
and (now I'm hoping for the connection) there would also be a method to load
the collection in one hit (sans OPF)
ie AddLines(!!) which would eventually fire
TBOCollection_DataSet_Adapter.PopulateCollection(aDataset: TDataset;
aCollection: TBusinesObjectCollection);
Regards
Kern
"Bob Dawson" <RBDawson (AT) prodigy (DOT) net> wrote
| Quote: | "Kern Carboni" wrote
How would I decipher this in light of your earlier response?
Not sure where you're seeing the disconnect--can you be a bit more
specific? |
|
|
| Back to top |
|
 |
Bob Dawson Guest
|
Posted: Sun Feb 20, 2005 2:24 am Post subject: Re: Help with BO design |
|
|
"Kern Carboni" wrote
| Quote: | ie. a TBusinessObject would have an AddLine method to create
a single instance and add to collection
|
Ahh--shorthand is throwing you off. Something like
aLineItem := aOrder.AddLine;
is really masking what's happening: the order object has an internal
TOrderLineItemsCollection, and that collection does the real work, not the
order instance.
Additionally (just to be clear), I'd expect an AddLine method to be adding a
new line item to the order, not loading an existing item.
| Quote: | and (now I'm hoping for the connection) there would also be a method
to load the collection in one hit (sans OPF)
|
I have an OPF, but I think it's possible--how about this:
First we have to talk about owned and unowned collections. If you think of
an ad hoc (unowned) collection like the patients seen on Friday, I'd expect
the application programmer to call a load method on the collection object
FridaysPatients := TPatientConnection.Create;
FridaysPatients.Load('ByDate',['18 Feb 2005']);
Now making this work without an OPF in place would be tricky, but I imagine
something like the following would work:
Create a datamodule for the TPatient class. In that datamodule is one query
having the SQL to load the patient class fields, and all other queries
contain only where clauses.
When the datamodule is created, a query manager records each query by name
in a list.
Now tracing the call
FridaysPatients.Load('ByDate',['18 Feb 2005']);
we have something like
the patientcollection instance calls a protected class method of the
patient collection class, which knows about the datamodule, so
instance call
FridaysPatients.Load('ByDate',['18 Feb 2005']);
goes to class call
class procedure TPatientCollection.Load(
aCollection : TPatientCollection;
const LoadCondition : string;
paramVals : array of variant);
Now the TPatientCollection class knows about the datamodule, so the call
gets relayed to the query manager object. It finds the master query
statement, and then appends the where clause from the 'ByDate' query (in its
list), iterates the variant array assigning parameter values, and fires the
query.
Then, the query and collection instance as passed on to the
| Quote: | TBOCollection_DataSet_Adapter.PopulateCollection(aDataset: TDataset;
aCollection: TBusinesObjectCollection);
lines so that the collection now has its objects. At that point the query |
can be discarded, and the call returns up the chain to the instance.
An owned collection is different only in that the application programmer
probably never loads the collection explicitly at all. Rather, one has a
lazy loader something like
property LineItems : TLineItemCollection read GetLineItems;
function TOrder.GetLineItems : TLineItemCollection;
begin
if not assigned (FLineItems) then
begin
FLineItems := TLineItemCollection.Create;
FLineItems.Load('ByOrderID', [self.ID]);
end;
Result := FLineItems;
end;
That's a pretty quick sketch of how the paddling underneath might work...
bobD
|
|
| Back to top |
|
 |
Bryan Crotaz Guest
|
Posted: Wed Feb 23, 2005 7:17 pm Post subject: Re: Help with BO design |
|
|
"Kern Carboni" <mlungu (AT) orcon (DOT) net.nz> wrote
| Quote: | Kiaora;
I am new to Delphi (1+ year) and was lucky enough to find this newsgroup
which has proved invaluable for my foray in OO;
Our current Radiology system is an Informix 3, dos based system, which I
have inherited in my new role. I have dedicated my sanity
to providing a modern GUI system and wanted to start on a good footing by
having the good people of this NG provide some guidance.
|
Before you go too much further, have a good look at Bold and ECO on the
Borland website, and come to
borland.public.delphi.modeldrivenarchitecture.general. That'll save you a
lot of time writing your own OPF, and enable you to get straight down to
your problem domain!
Bryan
|
|
| Back to top |
|
 |
|
|
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
|
|