Re: Mixing OO and DB

From: Robert Martin <unclebob_at_objectmentor.com>
Date: Sun, 2 Mar 2008 13:01:20 -0600
Message-ID: <2008030213012075249-unclebob_at_objectmentorcom>


On 2008-02-28 12:03:06 -0600, frebe <frebe73_at_gmail.com> said:

>> So, for instance, if we must fetch an employee record frequently in
>> various parts of our application it is better to use a function like
>> this:
>> 
>>   Employee e = Employee.find("Bob"):
>> 
>> Than it is to use raw SQL like this all through our app.
>> 
>>   DataRow e = exec("Select * from EmployeeTable where name = 'Bob';"

> );
>
> Why is the first line better than the last line?

It's smaller, more communicative, and can be polymorphically deployed.

>> Of course we can implement other kinds of 'find' methods.  
>> find_by_date, find_by_salary, etc, etc.  Every different query we use
>> on a regular basis, we can create a verb for in our DSL.  That verb is
>> a function call of some kind.

>
> And for queries we don't use on a regular basis? We can use "raw" SQL,
> or?

Write methods for them.

>> So we have not lost the power of the flexible query language.

>
> If you still allow "raw" SQL for queries not used on a regular basis,
> the power is not lost. But if you must have a find_by_xxx, for every
> possible select statement, the power is lost.

Not at all. All we are doing is giving each query a name. That name is the name of the method that is implemented by the SQL. This allows the programmer to commnicate the *intent* of the query, rather than it's implementation.

e.g. Employee.find_all_eligible_for_retirement() is a lot better than a long and complex SQL statement.
>
> What is the benefit with hiding SQL from the bulk of the application?

You can provide test implementations that don't use the database, but allow you to quickly test business rules.

>> That allows us to create a polymorphic API below which we can swap out
>> different database implementations, or even stubs and dummies .

>
> If you have a lot of find_by_xxx methods, swapping would still be
> quite difficult.

Swapping is done on a test by test basis. You don't have to swap everyting every time. For example, you want to test the functions that render all eligible employees in a scrolling list on a screen. You replace the Employee.find_all_eligible_employees method with an implementation that simply returns a canned list.

-- 
Robert C. Martin (Uncle Bob)  | email: unclebob_at_objectmentor.com
Object Mentor Inc.            | blog:  www.butunclebob.com
The Agile Transition Experts  | web:   www.objectmentor.com
800-338-6716                  |
Received on Sun Mar 02 2008 - 20:01:20 CET

Original text of this message