OOP and databases in the real-world

  • Thread starter Thread starter Fred Exley
  • Start date Start date
F

Fred Exley

I have a traditional application using a database and procedural code that
works fine. I'm re-writing it using the OOP methodology, just to see how
this may be the better way to do things. I think I've got a pretty good
grasp of the three pillars of OOP, and have objects properly defined using
inheritance, encapsulation, etc. as appropriate. Now it's time to do some
processing using real data, and the data resides on a relational database.

As best I can gather, the preferred OO way to do this in general is to:

Write a utility routine to load the data from the database into their
respective objects.

For tables in the database with a master/detail relationship (i.e., Order,
Order Items tables), represent this in OOP by creating another class, an
intersect object, that relates one Order with one Order Item instance.

Create yet another class, to be used as a container for these intersect
object items, using an ArrayList (to make use of that objects built-in
methods; insert, update, enumerate, etc.).

At this point, the actual data processing can begin. Create procedures that
solely operate on the objects we created, making use of the built-in methods
these objects provide, and writing our own methods as necessary.

When all the procedures are complete for whatever we're trying to do, use
another utility routine to write the resulting data transformations back to
the relational database we started with.

Is this about right? If so, doing it this way, what real-world advantages
do we now have using the OO methodology? Is all this added overhead really
worth it? The best scenario I can imagine is that maybe, once we've set
everything up in an OO model, the procedures that actually process that data
will be a fraction of the amount of procedural code required to simply
process against the database directly. In other words, is OOP really the
better way to go in real-world, production business applications, or is it
mainly a nice academic exercise? thanks

-Fred
 
First, the OOP methodology for working with a database varies greatly. A
database is simply a storage mechanism for any kind of data. The OOP
solution to working with the data is dependent entirely upon the usage of
the data and the business requirements involved.

IOW, there is no one OOP methodology for working with databases, any more
than there is one OOP methodology for working with files, or one OOP
methodology for working with any other form of data, stored or otherwise.

OOP is actually less of a methodoloy than a paradigm. It is a way of working
with and thinking about programming, with a number of extensions to
procedural programming that aid in the organization and usage of the code.
It is important to remember that all programming is procedural at heart,
including OOP. OOP is no more an academic exercise than high-level
programming languages are an academic exercise compared to pure machine
language.

OOP is a continuation of a series of derived principles that began with
Assembler language, continued to high-level languages, and is similar to the
use of functions, procedures, and structures in high-level programming
languages like C. It is a set of tools that facilitates the creation,
debugging, and maintenance of increasingly large and complex applications.

It is an abstraction of abstractions. Once you train yourself to think in an
object-oriented way, its power is apparent, and its usage becomes intuitive.
The hard part is re-training the way you think about programming in general.
As someone who started out doing procedural programming with C, I can
certainly understand the difficulty involved in making this change in one's
programming paradigm. It is similar in many ways to the change in paradigm
involved in understanding the mathematics of Calculus, or vector-based
graphics versus raster-based graphics. But it is well worth the time and
effort involved, as it leads to an exponential increase in one's programming
power. At least IMHO!

--
HTH,

Kevin Spencer
Microsoft MVP
Professional Numbskull

This is, by definition, not that.
 
You can get a startup example at:
http://spaces.msn.com/sholliday/ 5/24/2006 entry.

There is a link at the bottom .... in the refernces (birds eye view or
something like that)

Read that.

Since an Entity could have alot of child collections, I usually write an
Args class to encapsulate data ~~just for updating the db.

If you have an Emp class, and it has a child collection of
AllJobTitles
AllDepts

(and if the relationship is 1:N, aka, the Emp is in 1 Dept), when I update
the db, I don't want to send an object around with all those collections.

So I create a class like this

class EmpArgs : System.EventArgs
{
public string SSN { // implement this property }
public string LastName { // implement this property }
public string FirstName { // implement this property }
public string JobTitleId { // implement this property }
public int DeptId{ // implement this property }

}

I create that object in the presentation layer, I send it to the biz layer.
The biz layer will call the data layer. I actually convert the Arg into Xml
before sending it to the datalayer, because SqlServer2000 handles Xml very
well. I can't say the same for Oracle, but thats beside the point.

You'll probably think "There's alot of redundancy there".
Yep, but as the Emp objects "grows" over time, the seperation of the info
needed to create the Add/Edit Emp screen (presentation layer) ..... it
becomes important to streamline the Args class down to the bare necessities,
especially if you might ever go to remoting.

That's my $.02.

Good luck.
 
From what I am seeing here .. I cannnot disagree more. I could post up a 10
page note explaining some basics but instead I will point you to a few books
which cover the material.

As to why I disagree so stronly with the above code...

1) the class inherits from events args :-)
2) its not very OO, simply passing DTO's does not make your system object
oriented, the real question is where the behavior for that object lives
which is not discussed

Books:
Applying Domain Driven Design and Patterns, Jimmy Nilsson (not as theory
heavy more focused on implementation, uses nhibernate as an O/R mapper)
Domain Driven Design, Eric Evans (mostly theory)
P of EAA Fowler (mostly theory + a pattern reference)

Cheers,

Greg Young
 
"Fred Exley" <[email protected]> a écrit dans le message de (e-mail address removed)...

|I have a traditional application using a database and procedural code that
| works fine. I'm re-writing it using the OOP methodology, just to see how
| this may be the better way to do things. I think I've got a pretty good
| grasp of the three pillars of OOP, and have objects properly defined using
| inheritance, encapsulation, etc. as appropriate. Now it's time to do some
| processing using real data, and the data resides on a relational database.

The most important thing to remember when designing good OO systems is, not
to take an existing database design and try to make classes taht wrap the
data tables.

This will give you a very poor model compared with one that starts with
classes and then mapped to tables.

| As best I can gather, the preferred OO way to do this in general is to:
|
| Write a utility routine to load the data from the database into their
| respective objects.

Take a look at the concept of OPF (Object Persistence Frameworks) this is
designed to separate out anything to do with databases from the business
classes or UI.

| For tables in the database with a master/detail relationship (i.e., Order,
| Order Items tables), represent this in OOP by creating another class, an
| intersect object, that relates one Order with one Order Item instance.
|
| Create yet another class, to be used as a container for these intersect
| object items, using an ArrayList (to make use of that objects built-in
| methods; insert, update, enumerate, etc.).

The normal way of designing classes is to model the real world as closely as
possible, taking care not to use relational modelling as you would with
databases.

In the case of a "composite" class like a Sales Order with Order Lines, you
would simply design the following classes similar to this :

public class Order
{
public class Line
{
// private fields

public int Quantity { ... }

public Product Product { ... }

public decimal Total { ... }
}

public DateTime Date { ... }

public Customer { ... }

public ReadOnlyList<Line> Lines { ... }

public Line AddLine() { ... }

public void RemoveLine(Line line) { ... }
}

This arrangement assumes you are using .NET 2.0 where you can use nested
types to indicate that Line is only available within the context of Order.
The list of lines uses a generic list class that ensures that lines cannot
be added to or removed from the list except by using the methods provided in
the Order class; this further reinforces the idea that Lines cannot exist on
their own apart from the Order; their lives are governed by the life of the
Order.

| At this point, the actual data processing can begin. Create procedures
that
| solely operate on the objects we created, making use of the built-in
methods
| these objects provide, and writing our own methods as necessary.
|
| When all the procedures are complete for whatever we're trying to do, use
| another utility routine to write the resulting data transformations back
to
| the relational database we started with.

A good OPF should be able to translate objects into SQL statements and also
to construct SQL to retrieve objects as and when required, but any and all
processing should be completely inaccessible from outside of the OPF.

| Is this about right? If so, doing it this way, what real-world advantages
| do we now have using the OO methodology? Is all this added overhead
really
| worth it?

The real world advantages of using an OPF is to separate storage of objects
from the business logic af any applications that should want to store
objects from how those objects are stored.

After a good OPF is in place, then the advantages of well-designed classes
is that they allow data and the code that relates to that data to reside in
close union insode a single class; the term "responsibility driven design"
indicates that classes should be designed to be responsible for their own
well-being, nothing more nothing less.

In this regard, it is important to realise that there will be more classes
than those that map to tables; you will find classes that have no need to be
persisted but simply exist to connect and facilitate within the application
without necessarily being persistable.

| The best scenario I can imagine is that maybe, once we've set
| everything up in an OO model, the procedures that actually process that
data
| will be a fraction of the amount of procedural code required to simply
| process against the database directly. In other words, is OOP really the
| better way to go in real-world, production business applications, or is it
| mainly a nice academic exercise? thanks

There are many industrial strength applications out here that are designed
using OO - the whole .NET framework is designed using OO.

Joanna
 
Joanna Carter said:
"Fred Exley" <[email protected]> a écrit dans le message de (e-mail address removed)...

|I have a traditional application using a database and procedural code
that
| works fine. I'm re-writing it using the OOP methodology, just to see
how
| this may be the better way to do things. I think I've got a pretty good
| grasp of the three pillars of OOP, and have objects properly defined
using
| inheritance, encapsulation, etc. as appropriate. Now it's time to do
some
| processing using real data, and the data resides on a relational
database.

The most important thing to remember when designing good OO systems is,
not
to take an existing database design and try to make classes taht wrap the
data tables.

This will give you a very poor model compared with one that starts with
classes and then mapped to tables.

| As best I can gather, the preferred OO way to do this in general is to:
|
| Write a utility routine to load the data from the database into their
| respective objects.

Take a look at the concept of OPF (Object Persistence Frameworks) this is
designed to separate out anything to do with databases from the business
classes or UI.

| For tables in the database with a master/detail relationship (i.e.,
Order,
| Order Items tables), represent this in OOP by creating another class,
an
| intersect object, that relates one Order with one Order Item instance.
|
| Create yet another class, to be used as a container for these intersect
| object items, using an ArrayList (to make use of that objects built-in
| methods; insert, update, enumerate, etc.).

The normal way of designing classes is to model the real world as closely
as
possible, taking care not to use relational modelling as you would with
databases.

In the case of a "composite" class like a Sales Order with Order Lines,
you
would simply design the following classes similar to this :

public class Order
{
public class Line
{
// private fields

public int Quantity { ... }

public Product Product { ... }

public decimal Total { ... }
}

public DateTime Date { ... }

public Customer { ... }

public ReadOnlyList<Line> Lines { ... }

public Line AddLine() { ... }

public void RemoveLine(Line line) { ... }
}

This arrangement assumes you are using .NET 2.0 where you can use nested
types to indicate that Line is only available within the context of Order.
The list of lines uses a generic list class that ensures that lines cannot
be added to or removed from the list except by using the methods provided
in
the Order class; this further reinforces the idea that Lines cannot exist
on
their own apart from the Order; their lives are governed by the life of
the
Order.

| At this point, the actual data processing can begin. Create procedures
that
| solely operate on the objects we created, making use of the built-in
methods
| these objects provide, and writing our own methods as necessary.
|
| When all the procedures are complete for whatever we're trying to do,
use
| another utility routine to write the resulting data transformations back
to
| the relational database we started with.

A good OPF should be able to translate objects into SQL statements and
also
to construct SQL to retrieve objects as and when required, but any and all
processing should be completely inaccessible from outside of the OPF.

| Is this about right? If so, doing it this way, what real-world
advantages
| do we now have using the OO methodology? Is all this added overhead
really
| worth it?

The real world advantages of using an OPF is to separate storage of
objects
from the business logic af any applications that should want to store
objects from how those objects are stored.

After a good OPF is in place, then the advantages of well-designed classes
is that they allow data and the code that relates to that data to reside
in
close union insode a single class; the term "responsibility driven design"
indicates that classes should be designed to be responsible for their own
well-being, nothing more nothing less.

In this regard, it is important to realise that there will be more classes
than those that map to tables; you will find classes that have no need to
be
persisted but simply exist to connect and facilitate within the
application
without necessarily being persistable.

| The best scenario I can imagine is that maybe, once we've set
| everything up in an OO model, the procedures that actually process that
data
| will be a fraction of the amount of procedural code required to simply
| process against the database directly. In other words, is OOP really
the
| better way to go in real-world, production business applications, or is
it
| mainly a nice academic exercise? thanks

There are many industrial strength applications out here that are designed
using OO - the whole .NET framework is designed using OO.

Joanna

Thanks VERY much, Joanna -that's just what I was after! -Fred
 
"Fred Exley" <[email protected]> a écrit dans le message de (e-mail address removed)...

| Thanks VERY much, Joanna -that's just what I was after! -Fred

No problem, if you have any more questions on OO design, then get in touch.

One quick thought; there is a generic way to describe the Order/Line
relationship, remembering that an Order can be described as a relationship
between a Customer and a collection of OrderLines. Therefore we can abstract
out that relationship for use elsewhere.

public class OneToMany<ownerT, itemT>
{
private ownerT owner;

protected ownerT Owner
{
get { return owner; }
}

private List<itemT> items;

public ReadOnlyList<itemT> Lines
{
get { return new ReadOnlyList<itemT>(items); }
}

public itemT AddItem() { ... }

public void RemoveItem(ItemT line) { ... }
}

You can then write a storage routine that copes with this generic type, in
the OPF.

This can then be derived from in classes like Order :

public class Order : OneToMany<Customer, Order.Line>
{
public class Line
{
...
}

public Customer Customer
{
get { return Owner; }
}
}

Joanna
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top