 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Jose Luis Apuy Guest
|
Posted: Sun Feb 15, 2004 9:50 pm Post subject: OO Design question (accessing classes and attributes) |
|
|
hi,
I am new in the OO Desing and have some questions, sorry if I can not
explain my point well, I don't speak good english.
Fisrt of all I need some good examples about where the variables goes , how
to declare classes and how to access them from another classes, that help me
solving all this problems I am having in the meantime I will ask you this:
Let say I have something like this
TCustomer = class
Id : string;
Name : string;
LastName : string;
CreditAvailable : currency;
public
....
end;
another unit
unit DMCustomer;
//this unit takes care of the access to the database for TCustomer class
DMCustomer = class
//the following function should return a TCustomer object?
function getCustomer(customerId:integer):TCustomer;
// or should I declare a record to pass the TCustomer information thru the
different classes?
// cause in case it return a TCustomer I will make a circular reference with
TCustomer and DMCustomer
function setCustomer(whatShouldIpass?):boolean;
//and what about this function, should I pass a TCustomer object or a record
or what?
another question:
what about if I am in a classX that needs the information for a customer,
should the TCustomer class have a function that return an instance of
TCustomer and this function
should go to DMCustomer to get the information from the DB?
And this TClassX should have a variable customer : TCustomer to access the
methods for TCustomer, and how will it be the access?
TCustomer = class
Id : string;
Name : string;
LastName : string;
CreditAvailable : currency;
public
function getCustomer(customerId:string):TCustomer;
....
end;
unit ClassX;
type
TClassX = class
c1 : integer;
c2 : integer;
procedure X(X1:integer);
public
...
end;
implementation
var
customer : TCustomer;
procedure X(x1:integer);
begin
customer:=TCustomer.getCustomer(customer.text); //??????
end;
end.
thanks in advance...
Jose Luis
|
|
| Back to top |
|
 |
Joanna Carter (TeamB) Guest
|
Posted: Mon Feb 16, 2004 9:03 am Post subject: Re: OO Design question (accessing classes and attributes) |
|
|
Jose Luis Apuy wrote:
| Quote: | I am new in the OO Desing and have some questions, sorry if I can not
explain my point well, I don't speak good english.
Fisrt of all I need some good examples about where the variables goes
, how to declare classes and how to access them from another classes,
that help me solving all this problems I am having in the meantime I
will ask you this:
Let say I have something like this
TCustomer = class
Id : string;
Name : string;
LastName : string;
CreditAvailable : currency;
public
...
end;
|
To start with, you must learn to hide all variables from public view by
using properties or methods to access them. ALso, in your example, you are
using a string for the ID; I would recommend that you always use a
non-meaningful integer value for unique IDs.
TCustomer = class
private
fID: Integer;
fName: string;
fLastName: string;
fCreditAvailable: Currency;
function GetID: Integer;
procedure SetID(Value: Integer);
function GetName: string;
procedure SetName(const Value: string);
function GetLastName: string;
procedure SetLastName(const Value: string);
function GetCreditAvailable: Currency;
procedure SetCreditAvailable(Value: Integer)
public
property ID: Integer
read GetID
write SetID;
property Name: string
read GetName
write SetName;
property LastName: string
read GetLastName
write SetLastName;
property CreditAvailable: Currency
read GetCreditAvailable
write SetCreditAvailable;
end;
| Quote: | another unit
unit DMCustomer;
//this unit takes care of the access to the database for TCustomer
class
DMCustomer = class
//the following function should return a TCustomer object?
function getCustomer(customerId:integer):TCustomer;
// or should I declare a record to pass the TCustomer information
thru the different classes?
// cause in case it return a TCustomer I will make a circular
reference with TCustomer and DMCustomer
function setCustomer(whatShouldIpass?):boolean;
//and what about this function, should I pass a TCustomer object or a
record or what?
|
To do what you suggest about having a GetCustomer method on the Customer
class, you would have to have an instance of a customer in order to call the
method that gets the instance of the Customer; not a good idea :-(
Instead of having a regular instance method in TCustomer you could make it a
class method that does not need an instance to use it :
type
TCustomer = class
private
...
public
class function GetCustomer(ID: Integer): TCustomer;
...
end;
implementation
uses
CustomerDM;
var
DM: TCustomerDM;
class function TCustomer.GetCustomer(ID: Integer);
begin
if DM.CanFindCust(ID) then
begin
Result := Create;
Result.ID := ID;
DM.PopulateCustomer(Result);
end
else
Result := nil;
end;
....this could then be called like this :
var
aCust: TCustomer;
begin
aCust := TCustomer.GetCustomer(1234);
...
end;
But this will then tie your DM and class mutually together albeit in the
implementation section of the Customer unit, which would avoid circular
references.
Ideally, your TCustomer class should not know about how it is stored. This
will allow you to change how you store it at a later date without changing
your code.
So you need a generic data access class that takes the type of object that
you are trying to retrieve and to pass the 'empty' object to it in order to
get its details filled in.
e.g.
type
TObjectStore = class
public
class procedure GetObject(const Obj; TObject);
class procedure SaveObject(const Obj: TObject);
class procedure DeleteObject(const Obj: TObject);
end;
implementation
class procedure TObjectStore.GetObject(const Obj; TObject);
begin
if Obj.ClassType = TCustomer then
TDMCustomer.PopulateObject(TCustomer(Obj));
end;
....
This is called by :
var
aCust: TCustomer;
begin
aCust := TCustomer.Create;
aCust.ID := 1234;
TObjectStore.GetObject(aCust);
end;
Of course, this is very simplified and you should look up old messages in
this group on the subject of OPF (Object Persistence Frameworks) for a
comprehensive description of how to hide data storage from your objects.
Also I have some articles on OPF on my website www.carterconsulting.org.uk.
In the meanwhile what I have suggested above should get you going. Come back
if you get stuck :-)
Joanna
--
Joanna Carter (TeamB)
Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
|
|
| Back to top |
|
 |
Jose Luis Apuy Guest
|
Posted: Sun Feb 22, 2004 11:42 pm Post subject: Re: OO Design question (accessing classes and attributes) |
|
|
Tx a lot for the help, but.....
| Quote: | So you need a generic data access class that takes the type of object that
you are trying to retrieve and to pass the 'empty' object to it in order
to
get its details filled in.
e.g.
type
TObjectStore = class
public
class procedure GetObject(const Obj; TObject);
class procedure SaveObject(const Obj: TObject);
class procedure DeleteObject(const Obj: TObject);
end;
implementation
class procedure TObjectStore.GetObject(const Obj; TObject);
begin
if Obj.ClassType = TCustomer then
TDMCustomer.PopulateObject(TCustomer(Obj));
end;
...
This is called by :
var
aCust: TCustomer;
begin
aCust := TCustomer.Create;
aCust.ID := 1234;
TObjectStore.GetObject(aCust);
end;
|
you gave me this idea to retrieve, save and delete information to the DB
using objects,
but how can I do something similar to this but using records instead of
objects.
I have some structures that don't have any methods so I wrote them like
records but I don't know how to perform the operations to the db.
|
|
| Back to top |
|
 |
Malte Persike Guest
|
Posted: Mon Feb 23, 2004 12:44 am Post subject: Re: OO Design question (accessing classes and attributes) |
|
|
On Sun, 22 Feb 2004 17:42:35 -0600, "Jose Luis Apuy"
<japuy (AT) inetsoftware (DOT) com> wrote:
| Quote: | you gave me this idea to retrieve, save and delete information to the DB
using objects,
but how can I do something similar to this but using records instead of
objects.
I have some structures that don't have any methods so I wrote them like
records but I don't know how to perform the operations to the db.
|
IMHO, one ought to take as great effort as would be needed to avoid
records. Records can become a true plague especially with naturally
growing program designs. That records cannot be stored in a TList is
only one of the various drawbacks of records.
In the case you described I would simply convert the records to
classes. The problem arising with this approach is to carefully watch
for proper object destruction. Three ways to accomplish this would be:
1. Develop an unambigous responsibility scheme for destruction of
objects ("creating object must destroy");
2. Implement reference counting/smart pointers yourself. I don't know
if there are any ready-to-go free implementations available but there
definitely is a better solution.
3. And this would be Interfaces, which are inherently reference
counted. Hence, you would simply convert your records to classes and
then equip them with an interface.
--
The above e-mail address is not valid. To
contact me, please use my real e-mail address:
malte AT t DASH online DOT de
|
|
| Back to top |
|
 |
Joanna Carter (TeamB) Guest
|
Posted: Mon Feb 23, 2004 8:58 am Post subject: Re: OO Design question (accessing classes and attributes) |
|
|
"Malte Persike" <me (AT) privacy (DOT) net> a écrit dans le message de news:
[email]9mfi30dphls9i1fsvpni2robr66cckca77 (AT) 4ax (DOT) com[/email]...
| Quote: | That records cannot be stored in a TList is
only one of the various drawbacks of records.
|
But you can store pointers to records in a TList :-)
| Quote: | In the case you described I would simply convert the records to
classes. The problem arising with this approach is to carefully watch
for proper object destruction. Three ways to accomplish this would be:
|
I would totally agree with Malte; there is nothing wrong with using classes
that have no methods, only data; ust remember that classes give you a lot
more functionality.
As Malte said using interfaces also gives you a means of not having to worry
about disposing of objects, as long as you understand not to mix object and
interface references in the same code.
Using classes allows you to use RTTI or metadata to interogate the objects
passed for storage, allowing you to build generic SQL writers, etc rather
than writing custom storage classes for each type.
Take a look at those articles on OPF for some more ideas on this subject.
Joanna
--
Joanna Carter (TeamB)
Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
|
|
| Back to top |
|
 |
Malte Persike Guest
|
Posted: Mon Feb 23, 2004 11:56 pm Post subject: Re: OO Design question (accessing classes and attributes) |
|
|
On Mon, 23 Feb 2004 08:58:36 -0000, "Joanna Carter (TeamB)"
<joannac (AT) btinternetxx (DOT) com> wrote:
| Quote: |
But you can store pointers to records in a TList :-)
|
Hah, that reminds me of somthing which happened in the Delphi
introductory course I held at my university last week. The exercise
included writing an algorithm that would calculate the coordinates of
an arbitrary polyeder.
One of the students discovered the predefined TPoint record in the
Delphi help and wrote this code:
procedure CalcPolygonPoints(ANumber: Integer; AList: TList);
var
i: Integer;
pt: TPoint;
begin
// ...
for i:= 0 to Pred(ANumber) do begin
pt.x:= SomeValue;
pt.y:= SomeValue;
AList.Add(@pt);
end;
end;
Obviously this is a faulty implementation since all the pointers to
TPoint are referencing the same memory chunk and, moreover, go out of
scope when CalcPolygonPoints() exits. All the pointers in the TList
thus become invalidated. Nonetheless, the code might or might not
produce an AV, depending on subsequent allocations of memory.
I explained to the student that, if he wanted to stick to his
implementation, he needed to use a new/delete pointer logic to
accomplish his goal. A female student then asked: "Is there an
advantage over using my own TPoint class?". Well, there you go.
Cheerio,
Malte
--
The above e-mail address is not valid. To
contact me, please use my real e-mail address:
malte AT t DASH online DOT de
|
|
| 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
|
|