Discussion:
What is best ?
(too old to reply)
Stark
2012-06-06 17:41:31 UTC
Permalink
I am struggling with object orientation and I have a question for anybody
who can help. I am filling a window with columns of data representig account
monthly budgets for the year, Each account has 12 amounts which are proposed
by the program and the user may modify. Budget proposals are retrieved from
a Budget dataset where each record represents one account and has 12 fields
with the budgets amounts. Currently I simply gather the data accessing the
dataset and filling edits directly on the screen. When data are modified I
write them back to the dataset.
I started thinking on how to change this into a more object oriented thing.
I thought I would create a class whose properties are the Account and a
StringList where to store the 12 budgets. But how do I fill this object with
data ? Obviously from the dataset. So the question is: what is best: 1) use
the current procedure to gather the data and then copy the data into the
object or 2) create a method out of the current procedure ?

In the hope to xplain myself , following I try a possible implementation
showing the two alternatives: Can anyone comment ? Thanks.

type
TBudgtes = class(TComponent)
private
FAcc: string;
FMbudgets: TStrings;
protected
// two alternatives
procedure SetMbudgets(const Value: TStrings); virtual;
function GetMensiliBudget(aDataset: TDataset; aAccnt: string):
TStringList;
public
constructor Create(AOwner: TComponent);override;
destructor Destroy; override;
property Mbudgets: TStrings read FMbudgets write SetMbudgets;
end;

implementation

constructor TBudgets.Create(AOwner: TComponent);
begin
FMbudgets.Free; { I'll happily explain why this is here, but not now }
FMbudgets:= TStringList.Create;
inherited Create(Owner);
end;

destructor TBudgets.Destroy;
begin
FMbudgets.Free;
inherited Destroy;
end;

First alternative: this is to pick up values from a stringlist filled
outside

procedure TBudgets.SetMbudgets(const Value: TStrings);
begin
Mbudgets.Assign(Value);
end;

Second alternative: Pick up values using a method of the class

procedure TBudgets.SetMbudgets(aDataset: TDataset; aAccnt: string);
begin
GetBudgetsProposals(aDataset: TDataset; aAccnt: string);
end;
Maarten Wiltink
2012-06-07 08:26:31 UTC
Permalink
"Stark" <***@tin.it> wrote in message news:4fcf960a$0$1374$***@reader1.news.tin.it...

[...]
Post by Stark
In the hope to xplain myself , following I try a possible
implementation showing the two alternatives: Can anyone comment ?
Thanks.
type
TBudgtes = class(TComponent)
Why TComponent? As a rule, start with the minimum you need to make it
work. That's TObject. There may be a reason[0] to switch to TPersistent
in time. TComponent is almost never necessary.
Post by Stark
private
FAcc: string;
FMbudgets: TStrings;
Why TStrings? It gives you a list of strings that _happen_ to be
annotated with objects. But you don't need the strings.

Use TObjectList. Same rule as above.
Post by Stark
protected
// two alternatives
procedure SetMbudgets(const Value: TStrings); virtual;
TStringList;
I take it that's Italian for 'monthly'?
Post by Stark
public
constructor Create(AOwner: TComponent);override;
destructor Destroy; override;
property Mbudgets: TStrings read FMbudgets write SetMbudgets;
end;
implementation
constructor TBudgets.Create(AOwner: TComponent);
begin
FMbudgets.Free; { I'll happily explain why this is here, but not now }
To make the constructor work correctly on instances. Something that is
documented, but even the VCL itself does not live by.
Post by Stark
FMbudgets:= TStringList.Create;
inherited Create(Owner);
end;
destructor TBudgets.Destroy;
begin
FMbudgets.Free;
You are using the stringlist as a container for objects. Shouldn't
they be freed, too?
Post by Stark
inherited Destroy;
end;
First alternative: this is to pick up values from a stringlist filled
outside
procedure TBudgets.SetMbudgets(const Value: TStrings);
begin
Mbudgets.Assign(Value);
You have a big problem here. Assigning a TStrings to a TStrings will
copy the references to the objects. Now there are two references.
Which stringlist frees the objects in its own destructor?
Post by Stark
end;
Second alternative: Pick up values using a method of the class
procedure TBudgets.SetMbudgets(aDataset: TDataset; aAccnt: string);
begin
GetBudgetsProposals(aDataset: TDataset; aAccnt: string);
The name 'GetXxx' should, by convention, only be used for property
accessors. Other than that, this does offer better encapsulation.
Which is a nice way of saying that, when you have this, you still
know nothing. That isn't bad in itself, but in this case, it means
your problems is also not yet solved.
Post by Stark
end;
You are on your way to inventing Object Persistence; a standardised
way within your code to load and save objects to and from a database.

You are also going to have problems with memory leaks and double frees
at some point in the probably quite near future. Think carefully about
who 'owns' every object, and how your program knows that.

Groetjes,
Maarten Wiltink

[0] To wit, the Assign infrastructure.
Stark
2012-06-07 14:58:34 UTC
Permalink
Thank you for all of your comments. But I am still unclear on whether it is
reasonable to use an obiect oriented approach (my oo approach rather..).
I try to explain better what I am doing. I have a working program that does
basically the following:
- A function (GetBudgetProposals) accesses a dataset where each record
represents one account and has 12 fields with the budgets amounts and
retrieves the needed data which are retuned in a StringList.
- As many StringLists as many accounts are filled from the dataset. Each
StringList has the account number and 12 amounts.
- These data that are presented on the screen for the user to examine and
change.
- When done, all the data are written back on the budget dataset.

I am using this program to learn object orientation, which I know on theory.
My idea of using an oo approach was to create two class objects: the first,
for storing each single account data. The second for storing all of the
first object.
I am stuck at the first, which is the one I gave an example code of. I
though I had two alternatives:
-Use the above function to retrieve the data and then copy those into my
object when creating it, or
-Give the object itself this task thorough a similar function.

Just let me know if there is any sense in all this. I am sure I will learn
more from you, then reading bunch of books (which I am also doing..).

PS: As far as your suggestion to use TObjectLis, let me understand your
comment. What I am planning to store in this object is a serie of 12 amounts
(100, 150, .... 120). I thought I would need a StringList for this. Is this
wrong ?
You are using the stringlist as a container for objects...
The stringList will contaim amounts. Are they objects?
Maarten Wiltink
2012-06-07 15:49:05 UTC
Permalink
Post by Stark
Thank you for all of your comments. But I am still unclear on whether
it is reasonable to use an obiect oriented approach (my oo approach
rather..).
OO is not some fluke. It is a reasonable approach; you may assume that.
Post by Stark
I try to explain better what I am doing. I have a working program that
- A function (GetBudgetProposals) accesses a dataset where each record
represents one account and has 12 fields with the budgets amounts and
retrieves the needed data which are retuned in a StringList.
You don't need the stringlist, then. Make an Account object that has
twelve fields and reads them from (the current record in) the dataset.

(Again in the interest of minimality: pass the Fields of the dataset
to the object's loading procedure; that way it can read the current
record but not navigate to another record.)
Post by Stark
- As many StringLists as many accounts are filled from the dataset.
Each StringList has the account number and 12 amounts.
- These data that are presented on the screen for the user to examine
and change.
- When done, all the data are written back on the budget dataset.
I am using this program to learn object orientation, which I know on
the first, for storing each single account data. The second for storing
all of the first object.
Business object frameworks tend to introduce explicit classes for
collections of business objects. But at this stage, you can probably
use a mere TObjectList as a container for TAccount objects.
Post by Stark
I am stuck at the first, which is the one I gave an example code of. I
-Use the above function to retrieve the data and then copy those into
my object when creating it, or
You can do so directly, and right now it's a lot less confusing to do so.
Post by Stark
-Give the object itself this task thorough a similar function.
Just let me know if there is any sense in all this. I am sure I will
learn more from you, then reading bunch of books (which I am also
doing..).
PS: As far as your suggestion to use TObjectLis, let me understand
your comment. What I am planning to store in this object is a serie
of 12 amounts (100, 150, .... 120). I thought I would need a StringList
for this. Is this wrong ?
If you have twelve similar fields in a classtype, I'd still start by
declaring twelve fields (properties). There are lots of clever tricks
to exploit their similarity, but I wouldn't bother. Leave it for
version two.

If they are the budgets for each month in a year, use an array
indexed by an enumerated type.

You certainly don't _need_ a stringlist. Are these amounts even
strings? (They shouldn't be; monetary amounts should probably be
Currency.)
Post by Stark
You are using the stringlist as a container for objects...
The stringList will contaim amounts. Are they objects?
I don't know. You know that. What are they now?

Groetjes,
Maarten Wiltink
Stark
2012-06-08 12:59:00 UTC
Permalink
Post by Maarten Wiltink
You don't need the stringlist, then. Make an Account object that has
twelve fields and reads them from (the current record in) the dataset.
(Again in the interest of minimality: pass the Fields of the dataset
to the object's loading procedure; that way it can read the current
record but not navigate to another record.)
Thanks again for your comments. When I started thinking on this program, I
thought I could either use 12 fields, or an array, or a stringList. I choose
the stringList to make it easier to put these data into edits on the screen.
I think I will follow your suggestion to use 12 fields. But what you mean by
"pass the fields..." ? Can you esemplify that ?
Maarten Wiltink
2012-06-08 14:33:40 UTC
Permalink
Post by Maarten Wiltink
(Again in the interest of minimality: pass the Fields of the dataset
to the object's loading procedure; that way it can read the current
record but not navigate to another record.)
[...] what you mean by
"pass the fields..." ? Can you esemplify that ?
Forget it. It's not that important.

(If you want to make a case of it, read carefully: it said 'Fields',
not 'fields'. This is a property of a TDataSet object.)

Groetjes,
Maarten Wiltink
Rudy Velthuis
2012-06-07 20:28:20 UTC
Permalink
Post by Stark
Thank you for all of your comments. But I am still unclear on whether
it is reasonable to use an obiect oriented approach (my oo approach
rather..).
If you are not familiar with OO and only want to write a simple tool,
forget about it (unless you want to use the VCL or FireMonkey, then
you'll have to get acquainted with it, nolens volens).

Otherwise, get familiar with it. Learn its principles and follow some
tutorials, and you'll see why OO makes a lot of sense. It is not the
Holy Grail, but it makes many things a lot easier, once you understood
it.

But you must understand it to appreciate it. It's a bit like "learning"
to drink coffee or beer. The first time, they don't taste too well. <g>
--
Rudy Velthuis

"I would have made a good pope."
-- Richard Nixon
S.G
2012-06-07 22:07:55 UTC
Permalink
Post by Stark
- A function (GetBudgetProposals) accesses a dataset where each record
represents one account and has 12 fields with the budgets amounts and
retrieves the needed data which are retuned in a StringList.
- As many StringLists as many accounts are filled from the dataset. Each
StringList has the account number and 12 amounts.
- These data that are presented on the screen for the user to examine
and change.
- When done, all the data are written back on the budget dataset.
Two choices. Either you are now in phase starting to develop something
totally new and special. Or alternatively you are totally beginner in
writing simple Database application, using very common Data Controls.

To me that explanation looks like you should be able to read from your
database some budgeting data, each record containing 12 fields. Then you
show that data on your Form, in very traditional Excel type grid layout.
User can edit the data, and then save it back to the database.

That is the expression that I get from your explanation. And the answer
to write that functionality is to use standard TTable or TQuery
component TDataSource and TDbGrid to show that data on Form.
User can easily view, browse and edit the data, and then you write it
back to the database.

No need to start trying to understand anything about Object Orientation.
Just write the simple code and finish your budgeting application.
Post by Stark
I am using this program to learn object orientation, which I know on theory.
For learning purposes, I quess you should also find much of the wanted
OOP functionality and data reading/storing code, ready made, in the VCL
source code of those controls mentioned above.

S.G.
Hans-Peter Diettrich
2012-06-08 09:00:17 UTC
Permalink
Post by Stark
Thank you for all of your comments. But I am still unclear on whether it
is reasonable to use an obiect oriented approach (my oo approach rather..).
I try to explain better what I am doing. I have a working program that
- A function (GetBudgetProposals) accesses a dataset where each record
represents one account and has 12 fields with the budgets amounts and
retrieves the needed data which are retuned in a StringList.
- As many StringLists as many accounts are filled from the dataset. Each
StringList has the account number and 12 amounts.
- These data that are presented on the screen for the user to examine
and change.
- When done, all the data are written back on the budget dataset.
Since a stringlist *is* a class, question is whether this class is
appropriate for solving your problem.
Post by Stark
I am using this program to learn object orientation, which I know on
the first, for storing each single account data. The second for storing
all of the first object.
I am stuck at the first, which is the one I gave an example code of. I
-Use the above function to retrieve the data and then copy those into my
object when creating it, or
-Give the object itself this task thorough a similar function.
You can do that as you like, or as is easier to implement for you.
Post by Stark
Just let me know if there is any sense in all this. I am sure I will
learn more from you, then reading bunch of books (which I am also doing..).
PS: As far as your suggestion to use TObjectLis, let me understand your
comment. What I am planning to store in this object is a serie of 12
amounts (100, 150, .... 120). I thought I would need a StringList for
this. Is this wrong ?
A StringList holds strings. If you are happy with your amounts *being*
strings, then a StringList is a reasonable choice. Then you can store
all the StringList objects in an TObjectList. But you can store them
also in another StringList, using its Objects[] property for the lists,
and the Strings[] property for descriptive names.

When you have a database, then a DBGrid might be a better solution for
processing your data, because it already loads and stores the values
itself, and also manages the display and editing of the values.
Post by Stark
You are using the stringlist as a container for objects...
The stringList will contaim amounts. Are they objects?
The StringList contains strings. Whether these strings denote amounts is
up to the reader. If you e.g. want numeric values only, then the strings
only can be *representations* for numeric amounts, and the user should
be restricted to enter only strings which represent *valid* amounts.

When you separate the display and editing from the internal
representation of your data, then storing amounts *as* strings may not
be the right decision, even if it simplifies the transportation of the
amounts into GUI elements. Instead your classes should contain amounts
as numeric values, which are converted into strings when needed for
display/editing purposes, and back again after the user has edited an item.

I'd suggest that you rewrite your code, and replace the TStringLists by
something else, that better represents your data. You also didn't tell
us the database (table...) structure behind the DataSet, perhaps you
should change that, too, to contain numerical values instead of strings.
Then come back and ask again what's unclear to you.

DoDi
Stark
2012-06-08 13:17:40 UTC
Permalink
Post by Hans-Peter Diettrich
Post by Stark
Thank you for all of your comments. But I am still unclear on whether it
is reasonable to use an obiect oriented approach (my oo approach rather..).
I try to explain better what I am doing. I have a working program that
- A function (GetBudgetProposals) accesses a dataset where each record
represents one account and has 12 fields with the budgets amounts and
retrieves the needed data which are retuned in a StringList.
- As many StringLists as many accounts are filled from the dataset. Each
StringList has the account number and 12 amounts.
- These data that are presented on the screen for the user to examine and
change.
- When done, all the data are written back on the budget dataset.
Since a stringlist *is* a class, question is whether this class is
appropriate for solving your problem.
Post by Stark
I am using this program to learn object orientation, which I know on
the first, for storing each single account data. The second for storing
all of the first object.
I am stuck at the first, which is the one I gave an example code of. I
-Use the above function to retrieve the data and then copy those into my
object when creating it, or
-Give the object itself this task thorough a similar function.
You can do that as you like, or as is easier to implement for you.
Post by Stark
Just let me know if there is any sense in all this. I am sure I will
learn more from you, then reading bunch of books (which I am also doing..).
PS: As far as your suggestion to use TObjectLis, let me understand your
comment. What I am planning to store in this object is a serie of 12
amounts (100, 150, .... 120). I thought I would need a StringList for
this. Is this wrong ?
A StringList holds strings. If you are happy with your amounts *being*
strings, then a StringList is a reasonable choice. Then you can store
all the StringList objects in an TObjectList. But you can store them
also in another StringList, using its Objects[] property for the lists,
and the Strings[] property for descriptive names.
When you have a database, then a DBGrid might be a better solution for
processing your data, because it already loads and stores the values
itself, and also manages the display and editing of the values.
Post by Stark
You are using the stringlist as a container for objects...
The stringList will contaim amounts. Are they objects?
The StringList contains strings. Whether these strings denote amounts is
up to the reader. If you e.g. want numeric values only, then the strings
only can be *representations* for numeric amounts, and the user should
be restricted to enter only strings which represent *valid* amounts.
When you separate the display and editing from the internal
representation of your data, then storing amounts *as* strings may not
be the right decision, even if it simplifies the transportation of the
amounts into GUI elements. Instead your classes should contain amounts
as numeric values, which are converted into strings when needed for
display/editing purposes, and back again after the user has edited an item.
I'd suggest that you rewrite your code, and replace the TStringLists by
something else, that better represents your data. You also didn't tell us
the database (table...) structure behind the DataSet, perhaps you should
change that, too, to contain numerical values instead of strings. Then
come back and ask again what's unclear to you.
DoDi
I didn't tell about the database because I am still using Tables and BDE...
My budgeting data are held in currency format on the table and I think is
valid your suggestion to convert the amounts into string only when
trasporting them into the GUI elements. Also, the TDBGrid may semplify the
processing of my data. But I am presenting the budget data in different ways
to the user: one account at a time with its monthly amounts for the year, or
all of the accounts in tabular form, etc. The budget data will be those of
previous year, or calculated in various way and finally those defintely
accepted by the user. So I thought I would use this occasion to think OO in
some way ..
S.G
2012-06-13 07:16:16 UTC
Permalink
Post by Stark
I didn't tell about the database because I am still using Tables and
BDE... My budgeting data are held in currency format on the table and I
think is valid your suggestion to convert the amounts into string only
when trasporting them into the GUI elements. Also, the TDBGrid may
semplify the processing of my data. But I am presenting the budget data
in different ways to the user: one account at a time with its monthly
amounts for the year, or all of the accounts in tabular form, etc. The
budget data will be those of previous year, or calculated in various way
and finally those defintely accepted by the user. So I thought I would
use this occasion to think OO in some way ..
That is a simple every day Database Application. Also our customers are
happily using some old BDE applications every day in their Win7 64-bit
machines.

Your budgeting data can not contain any such things that could not be
done with standard Database Controls in Delphi.

If your main task and interest is in writing applications, and not
creating new Delphi Components, then your best used time is not trying
to learn more deeply about OOP. You should just put some more effort to
try learning how to use Table, Query, TMemoryDataset, TDbgrid, TDbEdit
etc controls. They can easily solve your whole problem.

The old MastApp application in your \Delphi\Demos sub directory is a
good starting point to see how those DB things work.

S.G.
Maarten Wiltink
2012-06-13 22:06:07 UTC
Permalink
"S.G" <***@none.special.ch> wrote in message news:jr9emj$pmu$***@speranza.aioe.org...
[...]
Post by S.G
If your main task and interest is in writing applications, and not
creating new Delphi Components, then your best used time is not trying
to learn more deeply about OOP. ...
Allow me to disagree. Violently.

I wouldn't dream of writing an application of any serious size without
modelling the data as objects. With encapsulation always, inheritance
where applicable, polymorphism where useful. Note that every application
form inherits from TForm, and declaring a field TStrings will incur
polymorphism.

Data-aware controls are for trivial problems. As soon as a data object
develops behaviour, they fall short.

Groetjes,
Maarten Wiltink
S.G
2012-06-14 07:08:42 UTC
Permalink
Post by Maarten Wiltink
Post by S.G
creating new Delphi Components, then your best used time is not trying
to learn more deeply about OOP. ...
Allow me to disagree. Violently.
I wouldn't dream of writing an application of any serious size without
modelling the data as objects. With encapsulation always, inheritance
where applicable, polymorphism where useful. Note that every application
form inherits from TForm, and declaring a field TStrings will incur
polymorphism.
By using the standard Delphi controls and components, you can write
applications and also Database Applications without knowing very deeply
about the OOP lying behind there.

I think this has been the whole idea in 'modern' application development
at least 10 years or more. Use such 'simple' development tools that you
can hire cheaper and more easily available developers.
Post by Maarten Wiltink
Data-aware controls are for trivial problems. As soon as a data object
develops behaviour, they fall short.
The background data for this specific budgeting problem has been given
and described in the opening message.
I do not see there _anything coming even close_ to that point that the
functionality of Data aware controls could not solve it.

If they would not, then you would need to start digging in to VCL code,
and see what kind of enhancements you would need to write there.

Yet, for _DB Application Developer_, it usually is always the more
expensive and slower alternative 'doing it yourself'. You seldom need
need to start writing massive amounts of VCL code just to build your own
enhanced Components and Controls.

The cheaper alternative is almost always already available on the
market. Buy some third party tools and controls, and you'll get your
problem solved within the budget and time scale.
S.G.
Stark
2012-06-15 14:47:12 UTC
Permalink
The old MastApp application in your \Delphi\Demos sub directory is a good
starting point to see how those DB things work.
S.G.
Possibly I didn't tell you that all works with regular Delphi components. My
idea was to use this simple application as a learning tool for OO
programming, since I had clear requirements and son on. But I understand I
am too old and my only result is to get discouraged those goodwilling people
that try to help me. I have two Delphi books, but OO is not explained in
depth and I findi it difficolt to find things in the net. I found two or
three articles that really start from scratch, with simple examples that
help understanding. I think I am learning the theory, but the practice in
another thing ..
Maarten Wiltink
2012-06-15 20:41:48 UTC
Permalink
[...] I understand I am too old
Allow me to disagree. Violently.
and my only result is to get discouraged those goodwilling people
that try to help me.
This is not grammatical English, and it is really not clear who is
getting discouraged. For what it's worth, I'm not.
[...] I think I am learning the theory, but the practice in another
thing ..
It is. But this is one of the advantages of age: to have learned that
there is time yet, everything need not be finished today, and even if
it is never finished, the water will continue to run down to the sea.

Groetjes,
Maarten Wiltink
Maarten Wiltink
2012-06-16 05:27:23 UTC
Permalink
Post by Maarten Wiltink
Post by Stark
and my only result is to get discouraged those goodwilling people
that try to help me.
This is not grammatical English, and it is really not clear who is
getting discouraged. For what it's worth, I'm not.
On reading it again, it _is_ grammatical English, although probably
by accident (no offence intended).

I'm still not (gotten) discouraged.

Groetjes,
Maarten Wiltink
Stark
2012-06-16 12:50:53 UTC
Permalink
Post by Maarten Wiltink
Post by Maarten Wiltink
Post by Stark
and my only result is to get discouraged those goodwilling people
that try to help me.
This is not grammatical English, and it is really not clear who is
getting discouraged. For what it's worth, I'm not.
On reading it again, it _is_ grammatical English, although probably
by accident (no offence intended).
I'm still not (gotten) discouraged.
Groetjes,
Maarten Wiltink
No offence.
and it's tragically true: "..the water will continue to run down to the sea
.."

Loading...