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 

Object oriented DB approach for Delphi7

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





PostPosted: Sat Oct 22, 2005 7:31 pm    Post subject: Object oriented DB approach for Delphi7 Reply with quote




In these days I'm trying to find an object oriented way for my db applications. I don't know much about it but I'm aware about the solutions like ECO etc. but i'm using Delphi7. So i need some suggestions.

Let's assume that i have some tables like this :

Customers
Products
Orders

Customers
Id
Name
Surname

Products
Id
Title
Price

Orders
Id
CustomerId
ProductId
Quantity

I have some classes created for to handle those tables like :

TCustomer(TObject)
- Id
- Name
- Surname

TProducts(TObject)
- Id
- Title
- Price

TOrders
- Id
- CustomerId
- ProductId
- Quantity

I've seen something like this from the http://www.techinsite.com.au/tiOPF/

But everything becomes so hard when i need to create some reports like this :

Customer Orders Count Order Totals
Linda Rusic 7 $12700
Jason Collins 11 $950

I had take a look at the Ray Konopka's "Creating Custom Delphi Components" book and some of his example about the business objects. In his samples, there was some business objects like mine, but each property of his classes was connected to the data source by the TField descendants. But i'm really confused about how can i create complex reports and lookup fields for my applications into an object oriented way. Is there any real object oriented solutions for the large scale applications ?

Thanks in advance,

Back to top
Joanna Carter [TeamB]
Guest





PostPosted: Sat Oct 22, 2005 8:46 pm    Post subject: Re: Object oriented DB approach for Delphi7 Reply with quote



"Rusic" <rusic (AT) nospam (DOT) com> a écrit dans le message de news:
435a9386$1 (AT) newsgroups (DOT) borland.com...

Quote:
In these days I'm trying to find an object oriented way for my db
applications. I don't know much about it but I'm aware about the solutions

like ECO etc. but i'm using Delphi7. So i need some suggestions.
Quote:

Let's assume that i have some tables like this :

Customers
Products
Orders

Customers
Id
Name
Surname

Products
Id
Title
Price

Orders
Id
CustomerId
ProductId
Quantity

I have some classes created for to handle those tables like :

TCustomer(TObject)
- Id
- Name
- Surname

TProducts(TObject)
- Id
- Title
- Price

TOrders
- Id
- CustomerId
- ProductId
- Quantity

To start with, a truly OO way of writing applications should not try to wrap
tables in classes, this is really only suitable when you have to code an
application for a legacy database. Ideally, tables are only necessary for
storage of instances of classes. Classes are not meant to be simply data
containers; they should also contain logic related to the class.

To comment on your example:

1. Only use singular nouns for class names

2. You would not hold a reference to a "foreign key" ID in a class, you
would instead hold a reference to an instance of the related class.

TCustomer
- Id: integer
- Name: string
- Surname: string

TProduct
- Id: integer
- Title: string
- Price: currency

TOrder
- Id
- Customer: TCustomer
- Product: TProduct
- Quantity: integer

But another thing you have to be aware of is when you fully model the Order
class. In an OO model you would do something like this :

TOrderLine
- Id: integer
- Quantity: integer
- Product: TProduct
- UnitPrice: currency
- Total: currency

TOrder
- Id: integer
- Ref: string
- Date: datetime
- Customer: TCustomer
- Lines: TOrderLineList
- Total: currency (calculated readonly)

Whereas the database tables would be differently organised :

OrderLine
- Id: integer
- OrderId: integer
- Quantity: integer
- ProductId: integer
- UnitPrice: currency
- Total: currency

TOrder
- Id: integer
- Ref: string
- Date: datetime
- CustomerId: integer

To resolve this, what is known as "impedance mismatch", you need to
institute a mapping between the properties and classes of the object layer
and the fields and tables of the database layer.

Quote:
I've seen something like this from the http://www.techinsite.com.au/tiOPF/

I have also written some articles on this subject on my website
www.carterconsulting.org.uk ; or search Google for this group for many
previous discussions on this topic.

Quote:
But everything becomes so hard when i need to create some reports like
this :

Customer Orders Count Order Totals
Linda Rusic 7 $12700
Jason Collins 11 $950

A good OPF (Object Persistence Framework) will allow this kind of querying,
but it is not a simple feature to incorporate due to the mismatch of fields
to properties.

Quote:
I had take a look at the Ray Konopka's "Creating Custom Delphi Components"
book and some of his example about the business objects. In his samples,

there was some business objects like mine, but each property of his classes
was connected to the data source by the TField descendants.

This way of connecting objects to tables is not to be recommended as it ties
your business layer too tightly to the database layer; see previous
discussions in this group.

Quote:
But i'm really confused about how can i create complex reports and lookup
fields for my applications into an object oriented way. Is there any real

object oriented solutions for the large scale applications ?

Take a look at the previous articles and posting in this group and then keep
on asking questions. There is a good variety of excellent OPF gurus here :-)

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer



Back to top
Bob Dawson
Guest





PostPosted: Sun Oct 23, 2005 12:52 am    Post subject: Re: Object oriented DB approach for Delphi7 Reply with quote



"Rusic" wrote
Quote:

But everything becomes so hard when i need to create some reports like
this :

Customer Orders Count Order Totals
Linda Rusic 7 $12700
Jason Collins 11 $950

Don't assume that just because something reads from the CUSTOMER table that
it has to be the same TCustomer class that a customer service application
would use. Reporting is a specific problem domain, and may require classes
entirely different than those used to maintain TCustomers in a production
application. If you're used to thinking in db schema terms, remember the
fact that that a reporting/archive database may have a different schema than
the OLTP database(s) that feed it:

Bottom line: Focusing too early on reports will tend to distort your objects
into data packets. Evolve your business classes to focus on behavior, and
don't saddle them immediately with reporting requirements. Reports don't
change data, so there's no real reason not to handle them separately.

Quote:
but each property of his classes was connected to the data source by the
TField descendants.


Nowadays, you'll generally see us advocate greater separation of
architectural layers: presentation layer, object layer, persistence layer,
and data access layer.

Quote:
there any real object oriented solutions for the large scale applications
?


What do you consider large? We handle tens of thousands of order line items
a day, each custom manufactured, and have tables seeing a million inserts a
week.

bobD



Back to top
Andrea Raimondi
Guest





PostPosted: Sun Oct 23, 2005 8:23 pm    Post subject: Re: Object oriented DB approach for Delphi7 Reply with quote

Rusic wrote:
Quote:
In these days I'm trying to find an object oriented way for my db applications. I don't know much about it but I'm aware about the solutions like ECO etc. but i'm using Delphi7. So i need some suggestions.
Thanks in advance,

Hi Rusic,

Many here will actually suggest(with reasoned arguments, actually)
that you should get an OPF for yourself. This is all good and
dandy as long as you *really* need to have database independence.

Yet, many times you happe to not really need that or, better, to
need that in a much milder way. Think for example of this: you
might need database independence to get a new ID for your primary key.

Or you need to insert some values.

Yet, you won't likely want to store your data to XML or to some
weirdo db that nobody uses.

Thus, it's since this morning that I'm playing with an idea:
instead of having to meddle with an OPF(which requires learning,
requires changing many habits), actually you just need a way to
generate queries that: either are general enough for use in any
database, or that can be generated using some code which will
make it easier for you to manage.

The whole idea is that you might have a situation like this:

TCustomerBO(Business object)
TCustomerPS(Persistence)

Now, if you can create an instance of the TCustomerPS class, assign
values to it via the BO's properties and then call a DBManager which
will actually generate the appropriate query based on YOUR code, then
this is probably going to be a *much* better approach then a full
blown OPF that you probably don't need. Let's put things in perspective,
just to make it clearer and let's go with an example of what I'm
playing with.

Let's say you have this kind of hierarchy:

Type

TSQLStatement = class
protected
function GetAsSQL : String;virtual;abstract;
public
property GetAsSQL : String read GetAsSQL;
end;

TSQLTableStatement = class(TSQLStatement)
public
property TableName : String;
property TableAlias : String;
end;

TSQLStatementList = class( TSQLStatement )
public
procedure Add(AStatement : TSQLStatement);
procedure Remove(AStatement: TSQLStatement);
// Count and items properties here... omitted for convenience
end;

TSQLJoinStatement = class( TSQLTableStatement )
public
property Condition : String;
end;

TSQLSelectStatement = class( TSQLTableStatement )
public
property StatementList : TSQLStatementList;
// read only property here
end;

Now, this is just a quick draft to explain the concept, I'm still
working on it. Now, assume you'd have a class like this:

Type
TDBType = (dbt_Firebird, dbt_SQLServer, dbt_Oracle);
TDBManager = class
public
constructor Create(ADB : TDBType);
function InitiateQuery( ABO : TCustomBO ) : TSQLStatement;
procedure Join( AJoinedBO : TCustomBO;AStatement : TSQLStatement);
procedure ExecQuery(out AResult : TResultSet);
end;

Ok. You can now, in your code, just create the DB manager when you
need it, do your stuff and then just dispose it.

This is, I think, pretty much what we're going to see with LINQ and
things like that - yet it's maybe "doable" already - and it would be
nice if we could collectively come up with something actually
sensible and useful.

Any comments?

Cheers,

Andrew

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.