There's been some talk about using Data Modules as an alternative solution
to designing BusinessObjects. The problem is that I've found very little in
the way of
examples and guidelines for this.
Does this mean that it's :
a) So self-explanatory that there's no need to explain it
b) It's never really used.
I would be glad for even the simplest sample projects. Either I'm missing
something
way obvious or something else.
Thank you in advance
Marcus
I'm curious if you could give an example/thread reference
of 'some talk,' i.e., a specific example that contributes
to 'your' confusion (...and maybe mine and others).
As a NOOD (Newbie Object Oriented Designer), I have found
this subject a bit (more like a few bytes, actually)
challenging also.
The terminology appears to be still in a major evolutionary
stage. You know, like 'Junk DNA?' We'll have to wait for the
chromosomes to shake out a bit. What one DOOD means by something
may not be the same as another DOOD.
I'm definitely not the best to teach on this subject, but then
again since I'm not too far along (or too far gone, whichever...),
maybe my need for a 'beginner's mind' is appropriate here.
My take so far is that a BO and a DataModule are NOT necessarily
the same thing.
A DataModule can contain Business Objects, i.e., Business Rules,
as code within the DataModule's events.
Yet it appears to me that the best practice suggests putting
the BOs into a seperate unit, but that in itself does not
necessarily mean that a DataModule is no longer necessary
or inappropriate.
I can recommend some threads from this ng:
Subject: What exactly IS a Business Object
Newsgroups: borland.public.delphi.oodesign
Date: 2001-01-11 09:49:05 PST
Subject: BO Persistence
Newsgroups: borland.public.delphi.oodesign
Date: 2001-01-03 14:10:52 PST
Subject: Re: BO Persistence - follow up
Newsgroups: borland.public.delphi.oodesign
Date: 2001-01-09 19:54:04 PST
Subject: BOs & Datasets - Who creates?
Newsgroups: borland.public.delphi.oodesign
Date: 2000-12-11 08:46:06 PST
Subject: My thoughts on BO's and stuff.
Newsgroups: borland.public.delphi.oodesign
Date: 2001-01-05 13:12:58 PST
Then of course, there's the always entertaining <g> brouhaha:
Subject: Data aware controls???
Newsgroups: borland.public.delphi.oodesign
Date: 2000/10/20
which usually breaks down into two or three general camps,
with Magister Niddery v The World < just kidding Wayne! >
But please don't equate my extensive familiarity and
access to these TomeThreads with any degree of understanding
and incite (...err 'insight'), thank you very much, but I'm
not giving up the struggle...<g>
> examples and guidelines for this.
>
> Does this mean that it's :
> a) So self-explanatory that there's no need to explain it
Exactly.
> b) It's never really used.
Never.
>
> I would be glad for even the simplest sample projects.
Impossible.
> Either I'm missing something
> way obvious or something else.
Both.
>
> Thank you in advance
> Marcus
You're entirely welcome.
--
George Newton
geo...@rabbithole.theworld.com
(x the rabbit... when sending email)
http://groups.google.com/groups?hl=sv&threadm=01bcf91c%2485e66280%242d0000c0
%40cesys002&rnum=5&prev=/groups%3Fq%3Ddelphi%2BBusiness%2BObjects%2BData%2Ba
ware%26hl%3Dsv
Response from Mark Smith about deriving from TDataModule rather than
TDataset
There's a bunch of similar but unfortunatelly my google deja links wouldn't
stay and are out of date.
Some of the variants mentioned looks about this.
TCustomer = class(TDataModule)
private:
etc
public
etc
end;
Thanks anyway, i'm going through your info piece for piece and see what I
can come up with.
I'm still at my trial and error stage when it comes to this.
"I'm using DataModules as your TBusinessObject. Not one big DataModule for
the entire project but smaller ones for each Business Object. This way I
still can use data-aware components. By the way, I never use Data Aware
components without cached updates on C/S development. I think this is a
good balance between ease of programming vs. performance."
Marcus
"Marcus J. Maunula" <marcus....@nospamtelia.com> skrev i meddelandet
news:3c207362_1@dnews...
Maybe more programmers than me don't understand what a data module has to do
with business objects at all ?
--
Bjoerge Saether
Asker, Norway
bjorge@hahaha_itte.no (remve the obvious)
PB's materials can be obtained from Borland Community's
CodeCentral. You want ID# 15511.
If all of this is getting you farther afield from where you
want to be, my apologies. My projects are so complex, that
I've been leaning toward the purist OOP/loose-coupled approach
in order to curtail the growth in the complexity/maintenance
of my projects.
I'm just trying to get a grip on what's being said in these threads :). And
of course to try it out myself
if I'd just find something to start with.
Marcus
"Bjørge Sæther" <bjorge@hahaha_itte.no> skrev i meddelandet
news:3c2079bd_1@dnews...
PB:s articles are awesome and really opened my eyes but I'd like to take
a look at the intermediate levels as well :). Thing is, i'd like to use
Data-aware here and there but
with the hardcore route it's hard. I know about the Dataset decendants but
so far I feel
like I'm wandering around in a desert :).
In short; I'm trying to find methods that I feel comfortable with and
doesn't require constant struggle
with techs(well at least to a point). Everything I do now is based on
standard use of D5:s components and
modules, only because there's projects that can't wait until I've mastered
these techniques. This is for the long term :).
Marcus
"George Newton" <geo...@rabbithole.theworld.com> skrev i meddelandet
news:3C2081B8...@rabbithole.theworld.com...
Marcus
I'm going to throw in a few thoughts that I have had when reading other
people mentioning this very subject. I am by no means an authority, and I
welcome any and all to comment on my comments <g>.
(1) A data module is an invisible container which many have advocated as a
place to put business objects which they have created to place on the
component palette. I haven't gotten far enough in my use of BO's to think of
them as components. Reusable, yes, but not necessarily needed on the
palette.
My BO's are defined in stand-alone units. In order to re-use them, I simply
include the unit in my project. There seems to me to be a bit of unnecessary
code and functionality accompanying a data module that steered my away from
inheriting from it.
(2) To my thinking, a data module indicates the ownership and use of
datasets, queries, etc.. Since virtually everyone agrees that BO's and
datasets should be kept separate, this would be counter-intuitive. Maybe if
it were named something other than TDataModule???
(3) I have not yet discovered/created any properties in my BO's which need
to be manipulated at design time. Once I have written my BO, it becomes
simply a matter of plugging them in and using them. When I want to change
the persistent mechanism used to save/load the BO's data, I simply change
the units used in the project. This is not controlled or owned by the BO,
but by the project.
I'm sure that there are some who do have published properties in there BO
which can be (and maybe need to be) manipulated at design time. Any comments
slash examples here would be very appreciated. Maybe my design is still too
immature for this.
For these reasons, I have chosen not to descend my BO's from TDataModule. My
framework is functional at this moment, but I have a lot of fleshing out to
do before it becomes production usable.
Hope this helps, either to answer your question, or to generate even more
discourse on this subject.
Regards
Jeff Eib
www.GarrettLiners.com
The idea is that you use a datamodule for each entity in your problem
domain (say customers). You can code all the event handlers to do
validation, etc.
As someone mentioned the advantage is that you can link it directly to
bound controls.
The disadvantage is that all the internals are public so encapsulation
goes out the window a bit.
Marc
Although I have no problem descending my BO from tComponent.
I also have no problem with building very flexible applications using
tDataModule as a non-GUI container for such BOs.
Descending from tComponent gives you plenty of advantages which really have
nothing to do directly with BOs, per se, but everything to do with
programming power inherent in Delphi. You *can* of course publish
properties to be set at design time. More importantly you can easily create
event handlers to make your tComponent/BOs highly reusable objects for
*other* programmers/situations not yet in existence. And also important, a
tComponent/BO can easily take advantage of RTTI which helps in the
serialization of the class to a persistent storage mechanism which is
another common topic concerning BOs in this newsgroup.
-dennis
"Jeffrey Eib, Sr." <je...@garrettliners.com> wrote in message
news:3c20af0f_1@dnews...
"Marcus J. Maunula" <marcus....@nospamtelia.com> wrote in message
news:3c207362_1@dnews...
And this is what is getting you in trouble.
The style of programming the VCL forces you into is *BAD*.
"Component-dropping" as I like to call it just doesn't prepare you for
developing your own BO framework or even understanding what's involved.
Do yourself a favor and start learning the "hard-core" techniques as you
call it.
Using the VCL "Component-dropping" style of programming may *seem* expedient
now, except then you have just created a legacy mess on your hands as soon
as you seriously want to consider design from a professional perspective.
TDatasets and TDatamodules are *not* BO's. The Data-aware components that
are included in the VCL are *not* BOs. To use them as the ancestors for
your framework is baseless in my opinion.
-dennis
> I also have no problem with building very flexible applications using
> tDataModule as a non-GUI container for such BOs.
>
> -dennis
>
Maybe this is what they meant then? This could be what was being talked
about.
Are there any small samples one could take a look at? (online or just some
project files someone could email)
Marcus
When one is first approaching the idea of developing business objects in
Delphi, Datamodules are a very common (and I think natural) choice. They are
designed to be containers primarily, though not exclusively, for data
components (TQuerys, etc) and have the advantage of Delphi's design-time
features for setting properties, events, and such on those components. Since
they are objects, it is also as easy as for any objects to design some
architecture around them in terms of how the allocation and lifetime of the
business objects is managed. I've used them this way on one very large
project (125+ datamodules, 250+ forms) with a great degree of success. Each
datamodule is focused on a logical grouping, such as queries and logic
required to manage customer data, another for product data, several covering
various financial needs, and so on.
However there are also limitations and disadvantages and I would not do it
the same way again.
One of the problems is that your business logic and persistence end up tied
together. Ideally they should be separate. Another problem is precisely
because they are datamodules, its *too* easy for programmers to add
components and methods as they decide they need to (not to mention coupling
to other modules) and, in a large project (many programmers), difficult to
keep under control.
Datamodules can still certainly be used, but I no longer base business
objects on them, rather business objects will *use* datamodules. IOW, I
think datamodules are still a reasonable choice as a base for the lowest
level (i.e. database-specific) persistence layer, but should not have any
business logic in them. This allows Delphi's design features to be used at
this level but keeps the persistence and the business logic separated. This
separation also makes it easier to control their use by others
--
Wayne Niddery (Logic Fundamentals, Inc.)
RADBooks: http://www.logicfundamentals.com/RADBooks/delphibooks.html
Try to make original mistakes, rather than needlessly repeating [others]. -
Donald Rumsfeld, U.S. Secretary of Defense.
Do you have anything small conceptual project/s one could look at? Just to
get the general picture. I sure have
tried the net without success (including all the hints and tips sites).
I've experimented a bit on my own but I've no idea if I'm on the right track
or not.
Thanks in advance anyway.
Marcus
"Wayne Niddery [TeamB]" <wnid...@aci.on.ca> skrev i meddelandet
news:3c218245_2@dnews...
> "Marcus J. Maunula" <marcus....@nospamtelia.com> wrote in message
> news:3c20609f$1_1@dnews...
(snip)
Interesting. How do you get info from the Datamodule to your BO? Using
ordinary Table.FieldByName('Widget').AsString or do you have Datamodule
properties with Get/Set procedures for each field in each of the
tables/queries?
Thanks.
Thom
Thom
I know of two approaches of transferring data from the BO to the DM. Neither
approach, however, allows the BO to have any knowledge of the
tables/queries/fields of the datamodule. This would bind the BO to a
specific persistence layer, and make changing say from say Interbase to
Oracle very difficult. When changing the persistence mechanism, there should
be no changes necessary in the BO.
In the first method, the data module has knowledge of the published
properties of the BO, and fills in its own query parameters using these
properties. This binds the DM to the BO, but that is the way it should be,
not the other way around. You normally don't want to use a Customer DM to
save Order information.
The second method has the BO stream its data, and then passing the stream to
the persistent mechanism, which then extracts the info from the stream for
persistence. This is sometimes controlled by a DM manager class, which
creates the stream, passes the stream to the BO to fill, and then passes it
to the DM for persistence.
HTH
Jeff Eib
www.GarrettLiners.com
There's several ways this can be done, Jeff gave you two variations.
As long as the actual database components in the datamodule are descended
from TDataset, then the BOs *can* be given direct access to them and those
datasets can still be interchanged without affecting the BO. This allows the
same BO to be used in either a two-tier or multitier situation since the BO
can be hooked up to ClientDatasets as easily as to TQuerys, etc.
This may be perfectly fine for some applications, but there is still a lot
of dependency this way (on particular fields and field types in the
datasets) and something like Jeff describes is better. Generally I create
specific persistence classes that know about one or more BOs and are able to
perform the appropriate database I/O for those BOs. It is these that
actually use the datamodules.
Speaking of Business Objects :) -> You might have a look at this stuff:
http://www.seleqt.com/
>There's been some talk about using Data Modules as an alternative solution
>to designing BusinessObjects. The problem is that I've found very little in
Best wishes
Kai Bohli
Norway
kai...@online.no
You mean you only want to look? And you promise not to touch? <g>
Do you get the feeling that this is really top-secret material?
I mean, did you ask a question...?
OK guys, correct me here, please, (if necessary) before I do
any damage:
I think there are no really simple examples, except in the sense
of the patterns.
Have you studied any of the patterns. PB's material utilizes
some of those concepts, and if you looked at the sample code
in that CodeCentral download, you'll get some help.
Also, look at this posting:
To: "Sergey Moshnikov" <ser...@yahoo.com>
From: "Mark Richter" <mric...@emceesoftware.com>
Subject: Re: Designing UI classes - what a mess!
Date: Wed, 24 Jan 2001 21:36:36 -0600
Groups: borland.public.delphi.oodesign
Mark gives a good basic set of Model View Controller units, that
have been of great help to me.
But you're correct that the kicker is the loose coupling between
the BO/DataObject and the actual Persistence.
My interpretation so far, is that this will be handled most
efficiently for my app by designing a descendent of TCollection
and TCollectionItem to pass to a descendent of TListView, to
handle the UI storage.
Yet the actual transfer of the data from the persistence,
according to the rules of the BO/DataObject, is still very
unclear to me...
"Jeffrey Eib, Sr." wrote:
>
> I know of two approaches of transferring data from the BO to the DM. Neither
> approach, however, allows the BO to have any knowledge of the
> tables/queries/fields of the datamodule. This would bind the BO to a
> specific persistence layer, and make changing say from say Interbase to
> Oracle very difficult. When changing the persistence mechanism, there should
> be no changes necessary in the BO.
>
> In the first method, the data module has knowledge of the published
> properties of the BO, and fills in its own query parameters using these
> properties. This binds the DM to the BO, but that is the way it should be,
> not the other way around. You normally don't want to use a Customer DM to
> save Order information.
>
> The second method has the BO stream its data, and then passing the stream to
> the persistent mechanism, which then extracts the info from the stream for
> persistence. This is sometimes controlled by a DM manager class, which
> creates the stream, passes the stream to the BO to fill, and then passes it
> to the DM for persistence.
>
...and...
"Wayne Niddery [TeamB]" wrote:
>
> There's several ways this can be done, Jeff gave you two variations.
>
> As long as the actual database components in the datamodule are descended
> from TDataset, then the BOs *can* be given direct access to them and those
> datasets can still be interchanged without affecting the BO. This allows the
> same BO to be used in either a two-tier or multitier situation since the BO
> can be hooked up to ClientDatasets as easily as to TQuerys, etc.
>
> This may be perfectly fine for some applications, but there is still a lot
> of dependency this way (on particular fields and field types in the
> datasets) and something like Jeff describes is better. Generally I create
> specific persistence classes that know about one or more BOs and are able to
> perform the appropriate database I/O for those BOs. It is these that
> actually use the datamodules.
>
Please don't get me wrong guys - you're all very helpful (well, all
except
for a few of you - and you know who you are <g>), but every time I read
paragraphs like these last few quoted above, it reminds me of Hesse's
'The Glass Bead Game' or the other title for 'Magister Ludi.'
Anybody read these? Know what I mean?
It's like the characters talk for days and months and years about
these 'things'...and, like, WHAT ARE They Talking About! The characters
never give an example, yet they are perfectly interested and willing and
able to go on talking about these things for years
'The Glass Bead Game'?
Is that anything like, 'Anybody Find My Marbles?'
Both variants (your first approach and the one you use now).
Thanks in advance
Marcus
"Wayne Niddery [TeamB]" <wnid...@aci.on.ca> skrev i meddelandet
news:3c23d6e8$1_2@dnews...
> "Thom Halvorsen" <th...@paperless.no> wrote in message
> news:3c2338f0_1@dnews...
> Do you get the feeling that this is really top-secret material?
> I mean, did you ask a question...?
>
Apparently since I can't find anything about it anywhere :).
> OK guys, correct me here, please, (if necessary) before I do
> any damage:
>
> I think there are no really simple examples, except in the sense
> of the patterns.
They don't have to be that simple, just give the right idea about it.
>
> Have you studied any of the patterns. PB's material utilizes
> some of those concepts, and if you looked at the sample code
> in that CodeCentral download, you'll get some help.
>
PB:s article and all but it's not what Wayne just described how he uses
DM:s.
There's a very simple reason for all this. I want to be able to use Dataset
decendants for
certain reasons. I already have an idea how you can do this through the
Outlook example but now
I would like to now how to do the same with Datamodules since it has been
mentioned but never
really shown how (well not to me at least).
That's really all :).
Marcus
For using DMs as business classes, there's really very little to it. You
create datamodules as you normaly would, drop down whatever datasets you
need, etc. The important thing is to think in terms of business classes when
planning the datamodules, i.e. a buisness class is focused on specific
logical problem domains. Create a datamodule who's sole purpose will be to
contain the data access and business rules / logic for customers. Create a
separate datamodule for handling products and another for handling sales,
etc.
The other key thing is *never, ever* allow a datamodule to contain a
reference to a form (i.e. do not add form units to the uses clauses in a
datamodule). This is crucial. Datamodules should not know about any
particualr form. By obeying this you make it possible for those datamodules
to be used, not only by any form, but by any *project*.
Forms use the datamodules as business classes. They create and use them as
needed. A form can use any number of datamodules, they aren't limited to
one.
Moving past that, I still create the datamodules, but I limit their
functionality to database I/O and create separate classes (in code-only
units) as business classes. These use the datamodules as necessary, and the
forms are limited to using the business classes only, a form never knows
about or uses a datamodule.
bobD
Seen the news?
http://www.headlinescanner.com/
"Wayne Niddery [TeamB]" <wnid...@aci.on.ca> wrote in message
news:3c252af0_1@dnews...
bobD
Seen the news?
http://www.headlinescanner.com/
"Wayne Niddery [TeamB]" <wnid...@aci.on.ca> wrote in message
news:3c252af0_1@dnews...
I still use data-aware controls and my arguments on this are still the same
(in fact I've just submitted an article to community on this identifying the
real issue, but being holiday time I don't expect it'll be up for a while).
My only real "transition" is that over time I have become tougher when it
comes to dealing with clients and will refuse work if the client insists on
not allowing me to perform reasonable (by my standards) requirements and
design for a project. In the past I would try to get this but would still
accept a project where I wasn't given this time and, as a result, expedience
ends up playing a big part during development. One cannot design proper
business classes and their relationships for a specific project unless time
is allocated for it and unfortunately it's still very difficult to convince
many clients that this is productive work, they still think we ought to be
able to "just code".
As for editing in grids, I haven't allowed that in a long time, though with
ClientDatasets there's less of an issue with this too.
For me, there are multiple issues, but I'll look forward to reading your
position.
> As for editing in grids, I haven't allowed that in a long time,
> though with ClientDatasets there's less of an issue with this
> too.
Depends, I suppose, on how/if you've wired the dataset to apply updates, and
whether all datasets necessarily have 1:1 relationships with the persistent
fields of the object whose collection they represent. I do agree that a
'disconnectable' dataset can be a qualitatively different beast than a
direct-updating query or table.
Happy Holidays to you and yours,
bobD
Thanks for the clarification.
Marcus
"Wayne Niddery [TeamB]" <wnid...@aci.on.ca> skrev i meddelandet
news:3c252af0_1@dnews...
(snip)
>
> For using DMs as business classes, there's really very little to it. You
> create datamodules as you normaly would, drop down whatever datasets you
> need, etc. The important thing is to think in terms of business classes
when
> planning the datamodules, i.e. a buisness class is focused on specific
> logical problem domains. Create a datamodule who's sole purpose will be to
> contain the data access and business rules / logic for customers. Create a
> separate datamodule for handling products and another for handling sales,
> etc.
(snip)